<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0"><id>tag:blogger.com,1999:blog-5221909926006253414</id><updated>2026-11-05T11:14:52.562+03:00</updated><category term="مقالات"/><category term="الشهادات الإحترافية"/><category term="java"/><category term="بايثون"/><category term="توعية"/><category term="HTML"/><category term="اساسيات البرمجة"/><category term="JavaScript"/><category term="لينكس"/><category term="cplusplus"/><category term="C"/><category term="Laravel"/><category term="php"/><category term="احتراف الأمن السيبراني"/><category term="CSS"/><category term="C Sharp"/><category term="قواعد البيانات"/><category term="أساسيات حاسوب"/><title type="text">نسور التقنية Nusur Tech</title><subtitle type="html">نسور التقنية هي منصة مجانية تقنية تطمح لمستقبل مشرق و تهتم لإثراء المحتوى العربي في شتى مجالات التقنية مثل الأمن السيبراني و البرمجة و الذكاء الإصطناعي و كل ما هو جديد.</subtitle><link href="https://www.nusurtech.ca/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default?redirect=false" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/" rel="alternate" type="text/html"/><link href="http://pubsubhubbub.appspot.com/" rel="hub"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default?start-index=26&amp;max-results=25&amp;redirect=false" rel="next" type="application/atom+xml"/><author><name>Nusur Tech</name><uri>http://www.blogger.com/profile/05603520431881492254</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqsmXmxgySZYIJgmIRVinRAZEFBg9R-EFB3_xJzE1PihxdbxDTDqUDnETBBzopbt97d79wqI9SxyE9dOoWLKr7yRc4eEWX4Ms55aGY9slxfVtGuOLkVhubvxO5tTXhkg/s113/173446919.jpg" width="32"/></author><generator uri="http://www.blogger.com" version="7.00">Blogger</generator><openSearch:totalResults>450</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><xhtml:meta content="noindex" name="robots" xmlns:xhtml="http://www.w3.org/1999/xhtml"/><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-4974935625500205277</id><published>2026-10-25T10:03:19.785+03:00</published><updated>2026-10-25T10:03:19.785+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">أشهر المنافذ والبروتوكولات في الشبكات</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8v1O_rFXI4YpnZ_0ZdNpvJnK_bv6w-w5i4vy6K55nz3OIC_te8eYGF7ouWjPHLtOVqNkk8StGOiawQKks2FIKA0mX5f_TjuCfyPpFMqaLRiS0vsfpk3FUSsVtmGKs02_8ngarQt7z8n-YucGTtX7ctTXlSv7FfHxcfCPCheQZzXG_rOZuAK0DSajiYu1j/s640/imageedit_1_6897195496.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="أشهر المنافذ والبروتوكولات في الشبكات (Common Network Ports &amp;amp; Protocols)" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8v1O_rFXI4YpnZ_0ZdNpvJnK_bv6w-w5i4vy6K55nz3OIC_te8eYGF7ouWjPHLtOVqNkk8StGOiawQKks2FIKA0mX5f_TjuCfyPpFMqaLRiS0vsfpk3FUSsVtmGKs02_8ngarQt7z8n-YucGTtX7ctTXlSv7FfHxcfCPCheQZzXG_rOZuAK0DSajiYu1j/s1600/imageedit_1_6897195496.webp" title="أشهر المنافذ والبروتوكولات في الشبكات (Common Network Ports &amp;amp; Protocols)" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;أشهر المنافذ والبروتوكولات في الشبكات Common Network Ports &amp;amp; Protocols&lt;/h3&gt;
&lt;p&gt;تُعدّ شبكات الحاسوب من أهم التقنيات التي تقوم عليها البنية التحتية الرقمية الحديثة، إذ تتيح للأجهزة والخوادم والتطبيقات تبادل البيانات والمعلومات عبر الشبكات المحلية والعالمية، بما في ذلك شبكة الإنترنت. وتعتمد عملية الاتصال بين هذه الأجهزة على مجموعة من القواعد والمعايير التي تُعرف بالبروتوكولات، إلى جانب المنافذ الشبكية التي تساعد على توجيه البيانات إلى الخدمات والتطبيقات المناسبة.&lt;/p&gt;
&lt;p&gt;ويُعدّ فهم أشهر المنافذ والبروتوكولات في الشبكات من الموضوعات الأساسية في علوم الحاسوب وتقنية المعلومات، خاصةً للمهتمين بمجالات إدارة الشبكات، وأمن المعلومات، والأمن السيبراني. فمعرفة هذه المنافذ واستخداماتها تساعد على فهم كيفية عمل الخدمات المختلفة، وتحليل حركة البيانات، واكتشاف مشكلات الاتصال، وتعزيز حماية الأنظمة من التهديدات الأمنية المحتملة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;أولًا: ما المقصود بمنافذ الشبكات (Network Ports)؟&lt;/h3&gt;
&lt;p&gt;منافذ الشبكات هي أرقام منطقية تُستخدم لتحديد الخدمات والتطبيقات التي تتواصل عبر الشبكة على الأجهزة والخوادم. فعندما يتصل المستخدم بخادم عبر الإنترنت، لا يكفي تحديد عنوان IP الخاص بالخادم فقط، بل يجب أيضًا تحديد الخدمة أو التطبيق الذي يستقبل الاتصال.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، عندما يفتح المستخدم موقعًا إلكترونيًا، يتصل المتصفح بخادم الويب عبر منفذ محدد يتوافق مع البروتوكول المستخدم. ويستخدم بروتوكول HTTP المنفذ 80 افتراضيًا، بينما يستخدم HTTPS المنفذ 443.&lt;/p&gt;
&lt;p&gt;تتراوح أرقام منافذ TCP وUDP من 0 إلى 65535، وتُقسم عادةً إلى ثلاث فئات رئيسية:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. المنافذ المعروفة (Well-Known Ports):&lt;/strong&gt; تتراوح من 0 إلى 1023، وتُستخدم عادةً في الخدمات الأساسية والشائعة، مثل HTTP وDNS وSSH.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. المنافذ المسجلة (Registered Ports):&lt;/strong&gt; تتراوح من 1024 إلى 49151، وتُستخدم من قِبل تطبيقات وخدمات مختلفة، مثل بعض أنظمة قواعد البيانات والتطبيقات المؤسسية.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. المنافذ الديناميكية أو الخاصة (Dynamic or Private Ports):&lt;/strong&gt; تتراوح من 49152 إلى 65535، وتُستخدم غالبًا كمنافذ مؤقتة لإنشاء اتصالات من أجهزة العملاء إلى الخوادم.&lt;/p&gt;
&lt;p&gt;ومن المهم معرفة أن رقم المنفذ لا يحدد الخدمة بصورة مؤكدة في جميع الحالات؛ إذ يمكن إعداد التطبيقات لاستخدام منافذ مختلفة عن المنافذ الافتراضية.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ثانيًا: ما المقصود ببروتوكولات الشبكات (Network Protocols)؟&lt;/h3&gt;
&lt;p&gt;بروتوكولات الشبكات هي مجموعة من القواعد والمعايير التي تنظّم عملية الاتصال وتبادل البيانات بين الأجهزة والأنظمة. وتحدد هذه البروتوكولات كيفية إرسال البيانات واستقبالها، وطريقة التعامل معها، وآليات معالجة الأخطاء، وفقًا لطبيعة كل بروتوكول.&lt;/p&gt;
&lt;p&gt;توجد بروتوكولات متعددة، يؤدي كل منها وظيفة معينة داخل الشبكة. فعلى سبيل المثال، يُستخدم HTTP لنقل محتوى صفحات الويب، ويُستخدم DNS للمساعدة في تحويل أسماء النطاقات إلى عناوين IP، بينما يُستخدم SSH لإدارة الخوادم عن بُعد بطريقة آمنة.&lt;/p&gt;
&lt;p&gt;وتعمل هذه البروتوكولات ضمن طبقات الشبكات المختلفة، بحيث تتكامل وظائفها لتوفير الاتصال بين التطبيقات والأجهزة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ثالثًا: الفرق بين بروتوكولي TCP وUDP&lt;/h3&gt;
&lt;p&gt;يُعدّ TCP وUDP من أهم بروتوكولات طبقة النقل، ويؤدي كل منهما دورًا مختلفًا في عملية تبادل البيانات.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;1. بروتوكول TCP&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يرمز TCP إلى Transmission Control Protocol، أي بروتوكول التحكم في الإرسال.&lt;/p&gt;
&lt;p&gt;يوفر هذا البروتوكول اتصالًا موثوقًا بين الطرفين، إذ يساعد على ترتيب البيانات، والتحقق من وصولها، وإعادة إرسال الأجزاء المفقودة عند الحاجة.&lt;/p&gt;
&lt;p&gt;ويُستخدم TCP في الخدمات التي تتطلب نقل البيانات بصورة موثوقة، مثل تصفح مواقع الويب باستخدام HTTP وHTTPS عبر TCP، ونقل الملفات، والاتصال بالخوادم عن بُعد باستخدام SSH.&lt;/p&gt;
&lt;p&gt;وتتمثل أهم مزاياه في موثوقية نقل البيانات، وترتيب الأجزاء المستلمة، وإدارة تدفق البيانات بين الطرفين.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;2. بروتوكول UDP&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يرمز UDP إلى User Datagram Protocol، أي بروتوكول مخطط بيانات المستخدم.&lt;/p&gt;
&lt;p&gt;يتميز هذا البروتوكول ببساطته وقلة العبء الناتج عن إدارة الاتصال، إذ لا يضمن بنفسه وصول جميع البيانات أو ترتيبها، ولا يعيد إرسال البيانات المفقودة تلقائيًا.&lt;/p&gt;
&lt;p&gt;ويُستخدم UDP في تطبيقات تتطلب سرعة الاستجابة أو تستطيع التعامل مع فقدان بعض البيانات، مثل المكالمات الصوتية والمرئية عبر الإنترنت، والألعاب الإلكترونية، واستعلامات DNS التقليدية.&lt;/p&gt;
&lt;p&gt;ولا يعني ذلك أن UDP أسرع في جميع الحالات، بل يعتمد الاختيار بينه وبين TCP على متطلبات التطبيق وطبيعة البيانات المتبادلة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;رابعًا: أشهر المنافذ والبروتوكولات في الشبكات&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;المنفذ 20 و21: بروتوكول FTP.&lt;/li&gt;&lt;li&gt;المنفذ 22: بروتوكول SSH.&lt;/li&gt;&lt;li&gt;المنفذ 23: بروتوكول Telnet.&lt;/li&gt;&lt;li&gt;المنفذ 25: بروتوكول SMTP.&lt;/li&gt;&lt;li&gt;المنفذ 53: بروتوكول DNS.&lt;/li&gt;&lt;li&gt;المنفذان 67 و68: بروتوكول DHCP.&lt;/li&gt;&lt;li&gt;المنفذ 80: بروتوكول HTTP.&lt;/li&gt;&lt;li&gt;المنفذ 110: بروتوكول POP3.&lt;/li&gt;&lt;li&gt;المنفذ 123: بروتوكول NTP.&lt;/li&gt;&lt;li&gt;المنفذ 143: بروتوكول IMAP.&lt;/li&gt;&lt;li&gt;المنفذان 161 و162: بروتوكول SNMP.&lt;/li&gt;&lt;li&gt;المنفذ 389: بروتوكول LDAP.&lt;/li&gt;&lt;li&gt;المنفذ 443: بروتوكول HTTPS.&lt;/li&gt;&lt;li&gt;المنفذ 445: بروتوكول SMB.&lt;/li&gt;&lt;li&gt;المنفذ 3306: بروتوكول MySQL.&lt;/li&gt;&lt;li&gt;المنفذ 3389: بروتوكول RDP.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;1. المنفذ 20 و 21 بروتوكول FTP&lt;/h3&gt;
&lt;p&gt;يرمز &lt;b&gt;FTP&lt;/b&gt; إلى File Transfer Protocol، ويُستخدم لنقل الملفات بين الأجهزة والخوادم عبر الشبكة.&lt;/p&gt;
&lt;p&gt;يُستخدم المنفذ 21 للتحكم في اتصالات FTP، بينما يُستخدم المنفذ 20 لنقل البيانات في نمط FTP النشط التقليدي. وقد تختلف المنافذ المستخدمة لنقل البيانات بحسب نمط التشغيل والإعدادات.&lt;/p&gt;
&lt;p&gt;وعلى الرغم من استخدام FTP في بعض البيئات، فإنه لا يوفر تشفيرًا افتراضيًا، مما قد يؤدي إلى تعرّض بيانات الدخول والملفات للاعتراض. لذلك يُفضّل استخدام بدائل أكثر أمانًا، مثل SFTP الذي يعمل عبر SSH، أو FTPS الذي يستخدم TLS لتشفير الاتصال.&lt;/p&gt;
&lt;h3&gt;2. المنفذ 22 بروتوكول SSH&lt;/h3&gt;
&lt;p&gt;يرمز &lt;b&gt;SSH&lt;/b&gt; إلى Secure Shell، وهو بروتوكول يُستخدم للاتصال الآمن بالأجهزة والخوادم عن بُعد.&lt;/p&gt;
&lt;p&gt;يسمح SSH لمسؤولي الأنظمة بتنفيذ الأوامر وإدارة الخوادم ونقل الملفات باستخدام أدوات متوافقة. ويعمل افتراضيًا عبر المنفذ 22 باستخدام TCP.&lt;/p&gt;
&lt;p&gt;ويُعدّ هذا البروتوكول من الأدوات المهمة في إدارة خوادم Linux وUnix، كما يُستخدم في إدارة البنية التحتية التقنية وتنفيذ المهام الإدارية عن بُعد.&lt;/p&gt;
&lt;p&gt;وتشمل ممارسات تأمينه استخدام المصادقة القوية، وتقييد الوصول إلى المستخدمين المصرح لهم، وتحديث البرامج، ومراقبة محاولات تسجيل الدخول غير المعتادة.&lt;/p&gt;
&lt;h3&gt;3. المنفذ 23 بروتوكول Telnet&lt;/h3&gt;
&lt;p&gt;يُستخدم Telnet لإنشاء اتصال نصي مع الأجهزة والخوادم البعيدة، وقد استُخدم تاريخيًا في إدارة الأجهزة وتنفيذ الأوامر عن بُعد.&lt;/p&gt;
&lt;p&gt;يعمل Telnet افتراضيًا عبر المنفذ 23 باستخدام TCP، لكنه لا يشفّر بيانات الاتصال افتراضيًا، بما في ذلك بيانات الدخول.&lt;/p&gt;
&lt;p&gt;لذلك يُعدّ SSH الخيار المفضّل في معظم حالات الإدارة عن بُعد، لأنه يوفر آليات تشفير ومصادقة أكثر أمانًا.&lt;/p&gt;
&lt;h3&gt;4. المنفذ 25 بروتوكول SMTP&lt;/h3&gt;
&lt;p&gt;يرمز SMTP إلى Simple Mail Transfer Protocol، ويُستخدم لإرسال رسائل البريد الإلكتروني بين خوادم البريد، كما يدخل ضمن منظومة إرسال الرسائل من التطبيقات إلى خوادم البريد.&lt;/p&gt;
&lt;p&gt;يُستخدم المنفذ 25 بصورة شائعة في نقل البريد بين الخوادم، بينما يُستخدم المنفذ 587 غالبًا لإرسال البريد من برامج المستخدمين إلى خوادم البريد، مع دعم آليات المصادقة والتشفير المناسبة.&lt;/p&gt;
&lt;p&gt;ويُعدّ SMTP عنصرًا أساسيًا في عمل أنظمة البريد الإلكتروني، إذ يتيح توجيه الرسائل وتسليمها بين الخوادم وفقًا لقواعد البروتوكول.&lt;/p&gt;
&lt;h3&gt;5. المنفذ 53 بروتوكول DNS&lt;/h3&gt;
&lt;p&gt;يرمز DNS إلى Domain Name System، ويُستخدم لتحويل أسماء النطاقات إلى عناوين IP، مما يسهّل على المستخدمين الوصول إلى المواقع الإلكترونية دون الحاجة إلى حفظ عناوينها الرقمية.&lt;/p&gt;
&lt;p&gt;فعندما يكتب المستخدم اسم موقع في المتصفح، قد يُرسل الجهاز استعلامًا إلى خادم DNS للحصول على عنوان IP المرتبط باسم النطاق.&lt;/p&gt;
&lt;p&gt;يستخدم DNS المنفذ 53 عبر UDP في كثير من الاستعلامات التقليدية، كما يستخدم TCP في حالات متعددة، منها نقل مناطق DNS وبعض الاستجابات التي تتطلب ذلك.&lt;/p&gt;
&lt;p&gt;ويؤدي DNS دورًا أساسيًا في عمل الإنترنت، لأن الوصول إلى عدد كبير من الخدمات يعتمد على القدرة على تحديد عناوين الخوادم باستخدام أسماء النطاقات.&lt;/p&gt;
&lt;h3&gt;6. المنفذان 67 و 68 بروتوكول DHCP&lt;/h3&gt;
&lt;p&gt;يرمز DHCP إلى Dynamic Host Configuration Protocol، ويُستخدم لتوزيع إعدادات الشبكة تلقائيًا على الأجهزة المتصلة بها.&lt;/p&gt;
&lt;p&gt;تشمل هذه الإعدادات عنوان IP، وقناع الشبكة، والبوابة الافتراضية، وعناوين خوادم DNS.&lt;/p&gt;
&lt;p&gt;في شبكات IPv4، يستخدم DHCP المنفذ 67 على الخادم والمنفذ 68 على العميل عبر UDP.&lt;/p&gt;
&lt;p&gt;وتكمن أهمية هذا البروتوكول في تقليل الحاجة إلى إعداد عناوين IP يدويًا على كل جهاز، مما يسهّل إدارة الشبكات الكبيرة ويحدّ من أخطاء الإعداد وتعارض العناوين.&lt;/p&gt;
&lt;h3&gt;7. المنفذ 80 بروتوكول HTTP&lt;/h3&gt;
&lt;p&gt;يرمز HTTP إلى Hypertext Transfer Protocol، ويُستخدم لتبادل البيانات بين متصفحات الإنترنت وخوادم الويب.&lt;/p&gt;
&lt;p&gt;عندما يطلب المستخدم صفحة إلكترونية، يرسل المتصفح طلبًا إلى خادم الويب، ثم يستقبل الاستجابة التي قد تحتوي على نصوص وصور وملفات وأنواع أخرى من المحتوى.&lt;/p&gt;
&lt;p&gt;يعمل HTTP تقليديًا عبر المنفذ 80 باستخدام TCP، لكنه لا يوفر تشفيرًا على مستوى HTTP نفسه.&lt;/p&gt;
&lt;p&gt;ولهذا السبب، تعتمد معظم المواقع الحديثة على HTTPS لحماية الاتصالات التي تتضمن بيانات المستخدمين أو عمليات تسجيل الدخول أو المعاملات الإلكترونية.&lt;/p&gt;
&lt;h3&gt;8. المنفذ 110 بروتوكول POP3&lt;/h3&gt;
&lt;p&gt;يرمز POP3 إلى Post Office Protocol Version 3، ويُستخدم لاستلام رسائل البريد الإلكتروني من خوادم البريد.&lt;/p&gt;
&lt;p&gt;يسمح هذا البروتوكول لبرامج البريد بالوصول إلى الرسائل وتنزيلها وفقًا لإعدادات الخادم والبرنامج المستخدم.&lt;/p&gt;
&lt;p&gt;يعمل POP3 تقليديًا عبر المنفذ 110، بينما يستخدم الإصدار المحمي بالتشفير، المعروف باسم POP3S، المنفذ 995 عادةً.&lt;/p&gt;
&lt;p&gt;ويختلف POP3 عن IMAP في طريقة إدارة الرسائل ومزامنتها، إذ يُستخدم IMAP عادةً عندما يحتاج المستخدم إلى إدارة الرسائل على الخادم ومزامنتها بين عدة أجهزة.&lt;/p&gt;
&lt;h3&gt;9. المنفذ 123 بروتوكول NTP&lt;/h3&gt;
&lt;p&gt;يرمز NTP إلى Network Time Protocol، ويُستخدم لمزامنة الوقت بين أجهزة الحاسوب والخوادم وأجهزة الشبكات.&lt;/p&gt;
&lt;p&gt;تساعد مزامنة الوقت على ضمان اتساق الطوابع الزمنية في سجلات الأنظمة، وهو أمر مهم في مراقبة الشبكات والتحقيق في الحوادث الأمنية وتشغيل الخدمات التي تعتمد على الوقت.&lt;/p&gt;
&lt;p&gt;يستخدم NTP المنفذ 123 عبر UDP عادةً، ويُعدّ من البروتوكولات المهمة في البيئات التقنية التي تحتاج إلى ضبط الوقت بصورة دقيقة.&lt;/p&gt;
&lt;h3&gt;10. المنفذ 143 بروتوكول IMAP&lt;/h3&gt;
&lt;p&gt;يرمز IMAP إلى Internet Message Access Protocol، ويُستخدم للوصول إلى رسائل البريد الإلكتروني وإدارتها على الخادم.&lt;/p&gt;
&lt;p&gt;يتيح هذا البروتوكول للمستخدم قراءة الرسائل وتنظيمها وحذفها ومزامنة التغييرات بين الأجهزة المختلفة، بحسب إعدادات الخدمة.&lt;/p&gt;
&lt;p&gt;يعمل IMAP تقليديًا عبر المنفذ 143، بينما يستخدم IMAPS المنفذ 993 عادةً لتوفير اتصال مشفر باستخدام TLS.&lt;/p&gt;
&lt;p&gt;ويُعدّ IMAP خيارًا شائعًا للمستخدمين الذين يرغبون في الوصول إلى حساب البريد الإلكتروني من الهاتف والحاسوب والأجهزة الأخرى مع الحفاظ على مزامنة الرسائل.&lt;/p&gt;
&lt;h3&gt;11. المنفذان 161 و 162 بروتوكول SNMP&lt;/h3&gt;
&lt;p&gt;يرمز SNMP إلى Simple Network Management Protocol، ويُستخدم لمراقبة أجهزة الشبكات وإدارة المعلومات المتعلقة بحالتها وأدائها.&lt;/p&gt;
&lt;p&gt;يمكن استخدامه في متابعة أجهزة التوجيه والمبدلات والطابعات والخوادم، وجمع معلومات مثل حالة الواجهات واستهلاك الموارد وأخطاء الاتصال.&lt;/p&gt;
&lt;p&gt;يستخدم SNMP المنفذ 161 عادةً للاستعلامات والإدارة، بينما يُستخدم المنفذ 162 غالبًا لاستقبال التنبيهات المعروفة باسم Traps.&lt;/p&gt;
&lt;p&gt;وتتطلب الإدارة الآمنة استخدام إصدارات وإعدادات مناسبة، وتقييد الوصول إلى خدمات المراقبة، لأن الإعدادات الضعيفة قد تكشف معلومات مهمة عن البنية التحتية للشبكة.&lt;/p&gt;
&lt;h3&gt;12. المنفذ 389 بروتوكول LDAP&lt;/h3&gt;
&lt;p&gt;يرمز LDAP إلى Lightweight Directory Access Protocol، ويُستخدم للوصول إلى خدمات الدليل التي تنظّم معلومات المستخدمين والمجموعات والأجهزة والموارد داخل المؤسسات.&lt;/p&gt;
&lt;p&gt;تساعد هذه الخدمات في إدارة الهويات والبحث عن الحسابات وتطبيق بعض آليات المصادقة والتكامل مع الأنظمة المؤسسية.&lt;/p&gt;
&lt;p&gt;يستخدم LDAP المنفذ 389 افتراضيًا، ويمكن حماية الاتصالات باستخدام TLS وفقًا لطريقة الإعداد، بينما يُستخدم المنفذ 636 عادةً لاتصالات LDAP عبر TLS منذ بداية الاتصال.&lt;/p&gt;
&lt;p&gt;وتظهر أهمية LDAP في المؤسسات التي تحتاج إلى إدارة مركزية للحسابات والصلاحيات.&lt;/p&gt;
&lt;h3&gt;13. المنفذ 443 بروتوكول HTTPS&lt;/h3&gt;
&lt;p&gt;يُعدّ HTTPS من أهم البروتوكولات المستخدمة في الإنترنت الحديث، وهو نسخة من HTTP تعمل عبر اتصال محمي باستخدام TLS.&lt;/p&gt;
&lt;p&gt;يساعد HTTPS على تشفير البيانات أثناء انتقالها، والتحقق من هوية الخادم، وحماية سلامة المعلومات المتبادلة بين المتصفح والخادم.&lt;/p&gt;
&lt;p&gt;يستخدم HTTPS المنفذ 443 عادةً. وفي الاستخدام التقليدي لـ HTTP/1.1 وHTTP/2، يعمل عبر TCP، بينما يستخدم HTTP/3 بروتوكول QUIC المبني على UDP.&lt;/p&gt;
&lt;p&gt;ويُستخدم HTTPS في تسجيل الدخول إلى الحسابات، والتسوق الإلكتروني، والخدمات المصرفية، والمنصات التعليمية، ومعظم المواقع الحديثة.&lt;/p&gt;
&lt;h3&gt;14. المنفذ 445 بروتوكول SMB&lt;/h3&gt;
&lt;p&gt;يرمز SMB إلى Server Message Block، ويُستخدم لمشاركة الملفات والطابعات والموارد بين الأجهزة، خصوصًا في شبكات المؤسسات التي تعتمد على أنظمة Windows.&lt;/p&gt;
&lt;p&gt;يعمل SMB عادةً عبر TCP على المنفذ 445، ويسمح للمستخدمين المصرح لهم بالوصول إلى الملفات والمجلدات المشتركة وفقًا للصلاحيات المحددة.&lt;/p&gt;
&lt;p&gt;وعلى الرغم من أهمية هذا البروتوكول في البيئات المؤسسية، فإن تعريض المنفذ 445 للإنترنت قد يعرّض الأنظمة لمخاطر أمنية. لذلك ينبغي تقييد الوصول إليه، وتحديث الأنظمة، وتطبيق صلاحيات مناسبة، وتجنب إتاحته خارجيًا دون حاجة وضوابط واضحة.&lt;/p&gt;
&lt;h3&gt;15. المنفذ 3306 بروتوكول MySQL&lt;/h3&gt;
&lt;p&gt;يُستخدم المنفذ 3306 افتراضيًا للاتصال بخوادم قواعد بيانات MySQL عبر TCP.&lt;/p&gt;
&lt;p&gt;تتيح قواعد البيانات تخزين المعلومات وتنظيمها واسترجاعها، وتُستخدم في تطبيقات الويب والمتاجر الإلكترونية وأنظمة إدارة المحتوى والأنظمة المؤسسية.&lt;/p&gt;
&lt;p&gt;فعلى سبيل المثال، عندما يسجل المستخدم حسابًا جديدًا في موقع إلكتروني، قد يتصل التطبيق بخادم قاعدة البيانات لحفظ معلومات الحساب وفقًا لبنية النظام وإعداداته.&lt;/p&gt;
&lt;p&gt;ومن الناحية الأمنية، ينبغي تقييد الوصول إلى خادم قاعدة البيانات بحيث لا يتمكن من الاتصال به إلا التطبيق أو المستخدمون المصرح لهم، مع استخدام المصادقة القوية والتشفير عند الحاجة.&lt;/p&gt;
&lt;h3&gt;16. المنفذ 3389 بروتوكول RDP&lt;/h3&gt;
&lt;p&gt;يرمز RDP إلى Remote Desktop Protocol، ويُستخدم للاتصال بسطح المكتب البعيد في أنظمة Windows، مما يسمح للمستخدم بالتفاعل مع جهاز آخر عبر الشبكة.&lt;/p&gt;
&lt;p&gt;يُستخدم المنفذ 3389 افتراضيًا في كثير من إعدادات RDP، ويمكن أن يعتمد الاتصال على TCP وUDP.&lt;/p&gt;
&lt;p&gt;ويُستخدم هذا البروتوكول في الإدارة التقنية والدعم عن بُعد، لكنه يحتاج إلى حماية مناسبة، لأن إتاحته دون ضوابط قد تزيد من مخاطر محاولات الدخول غير المصرح بها.&lt;/p&gt;
&lt;p&gt;وتشمل ممارسات الحماية استخدام المصادقة متعددة العوامل حيثما أمكن، وتقييد الوصول عبر الشبكات الموثوقة أو VPN، وتحديث الأنظمة، ومراقبة محاولات تسجيل الدخول.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;خامسًا: أهمية المنافذ والبروتوكولات في الأمن السيبراني&lt;/h3&gt;
&lt;p&gt;تمثل المنافذ والبروتوكولات عنصرًا مهمًا في أمن الشبكات، لأنها تحدد كيفية وصول التطبيقات والأجهزة إلى الخدمات المختلفة وتبادل البيانات فيما بينها.&lt;/p&gt;
&lt;p&gt;وتساعد معرفة هذه المنافذ على تحديد الخدمات المتاحة، وفهم الاتصالات التي تنشئها التطبيقات، ومراجعة الإعدادات الأمنية للخوادم والأجهزة.&lt;/p&gt;
&lt;p&gt;وتظهر أهميتها في عدة جوانب، من أبرزها:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;اكتشاف الخدمات:&lt;/strong&gt; تساعد معرفة المنافذ الشائعة على تحديد الخدمات المحتمل تشغيلها على الأجهزة، مع ضرورة التحقق من الخدمة الفعلية وعدم الاعتماد على رقم المنفذ وحده.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;إدارة جدران الحماية:&lt;/strong&gt; تتيح جدران الحماية تحديد الاتصالات المسموح بها والمرفوضة وفقًا لسياسات الأمن المعتمدة، مما يساعد على الحد من الاتصالات غير الضرورية.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;تقليل سطح الهجوم:&lt;/strong&gt; يؤدي تعطيل الخدمات غير المستخدمة وإغلاق المنافذ التي لا توجد حاجة إليها إلى تقليل نقاط الدخول المحتملة إلى الأنظمة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;اكتشاف البروتوكولات غير الآمنة:&lt;/strong&gt; تساعد معرفة خصائص البروتوكولات على اكتشاف الإعدادات التي قد تعرض البيانات للخطر، مثل استخدام Telnet أو FTP التقليدي دون تشفير.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;مراقبة حركة الشبكة:&lt;/strong&gt; يمكن تحليل الاتصالات والمنافذ المستخدمة للمساعدة في اكتشاف الأنشطة غير المعتادة وتشخيص المشكلات الأمنية والتشغيلية.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;حماية الخدمات الحساسة:&lt;/strong&gt; يساعد تقييد الوصول إلى قواعد البيانات وخدمات مشاركة الملفات وأدوات الإدارة عن بُعد على تقليل احتمالات الوصول غير المصرح به.&lt;/p&gt;
&lt;p&gt;ومن المهم التأكيد أن وجود منفذ مفتوح لا يعني بالضرورة أن الجهاز مخترق، كما أن إغلاق بعض المنافذ لا يكفي وحده لضمان أمن النظام؛ إذ يعتمد الأمن على مجموعة متكاملة من الإجراءات، تشمل تحديث البرامج، وإدارة الصلاحيات، والتشفير، والمصادقة، ومراقبة الأنظمة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;سادسًا: كيف يمكن فحص المنافذ عمليًا؟&lt;/h3&gt;
&lt;p&gt;يمكن تطبيق المفاهيم السابقة باستخدام أدوات متوفرة في أنظمة التشغيل، بهدف التعرف على الاتصالات والمنافذ المستخدمة، بشرط إجراء الاختبارات على الأجهزة والشبكات التي يملك المستخدم تصريحًا بفحصها.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. فحص الاتصالات في Windows&lt;/h4&gt;
&lt;p&gt;يمكن فتح موجه الأوامر (Command Prompt) وتشغيل الأمر التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;netstat -ano
&lt;/pre&gt;
&lt;p&gt;يعرض هذا الأمر معلومات عن الاتصالات الشبكية، والمنافذ التي تستمع إليها التطبيقات، وأرقام العمليات المرتبطة بها.&lt;/p&gt;
&lt;p&gt;ويمكن أيضًا استخدام الأمر التالي في PowerShell لعرض اتصالات TCP التي تستمع إلى الاتصالات الواردة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Get-NetTCPConnection -State Listen
&lt;/pre&gt;
&lt;p&gt;تساعد هذه الأوامر على فهم الاتصالات المحلية، لكنها لا تعني أن كل منفذ ظاهر متاح بالضرورة من الإنترنت؛ فقد تمنع جدران الحماية أو إعدادات الشبكة الوصول إليه.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. اختبار الاتصال بمنفذ محدد&lt;/h4&gt;
&lt;p&gt;يمكن استخدام الأمر التالي في PowerShell لاختبار اتصال TCP بمنفذ HTTPS على نطاق مخصص للأمثلة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Test-NetConnection example.com -Port 443
&lt;/pre&gt;
&lt;p&gt;يساعد هذا الاختبار على التحقق مما إذا كان بالإمكان إنشاء اتصال TCP بالوجهة والمنفذ المحددين من بيئة الاختبار.&lt;/p&gt;
&lt;p&gt;لكن نجاح الاتصال لا يثبت وحده أن الخدمة تعمل بصورة سليمة أو أن الاتصال آمن بالكامل.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. استخدام أداة Nmap&lt;/h4&gt;
&lt;p&gt;تُستخدم أداة Nmap في استكشاف الأجهزة والخدمات والمنافذ ضمن الشبكات، وهي من الأدوات المعروفة لدى مسؤولي الشبكات ومتخصصي الأمن السيبراني.&lt;/p&gt;
&lt;p&gt;يمكن، في مختبر محلي أو على جهاز تملكه، استخدام الأمر التالي لفحص مجموعة من المنافذ الشائعة على الجهاز المحلي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;nmap -sT -F 127.0.0.1
&lt;/pre&gt;
&lt;p&gt;يفحص هذا الأمر مجموعة من المنافذ الشائعة على عنوان الجهاز المحلي باستخدام فحص اتصال TCP.&lt;/p&gt;
&lt;p&gt;ويجب عدم إجراء فحوصات على أجهزة أو شبكات الآخرين دون إذن صريح، مع الالتزام بالقوانين والسياسات الأمنية المعمول بها.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;سابعًا: أفضل الممارسات لتأمين منافذ الشبكات&lt;/h3&gt;
&lt;p&gt;لتحسين مستوى الحماية في الشبكات والأنظمة، ينبغي الالتزام بمجموعة من الممارسات الأمنية، من أهمها:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;إغلاق المنافذ والخدمات التي لا توجد حاجة تشغيلية إليها.&lt;/li&gt;
&lt;li&gt;استخدام جدران الحماية لتقييد الاتصالات الواردة والصادرة وفقًا لسياسة أمنية واضحة.&lt;/li&gt;
&lt;li&gt;تفضيل البروتوكولات المشفرة، مثل HTTPS وSSH، على البدائل التي تنقل البيانات دون تشفير.&lt;/li&gt;
&lt;li&gt;تحديث أنظمة التشغيل والخوادم والتطبيقات بصورة دورية لمعالجة الثغرات الأمنية المعروفة.&lt;/li&gt;
&lt;li&gt;استخدام كلمات مرور قوية وتفعيل المصادقة متعددة العوامل عند توافرها.&lt;/li&gt;
&lt;li&gt;عدم إتاحة خدمات قواعد البيانات ومشاركة الملفات للإنترنت دون ضرورة وضوابط مناسبة.&lt;/li&gt;
&lt;li&gt;مراقبة سجلات الشبكة والخوادم للكشف عن محاولات الاتصال غير المعتادة.&lt;/li&gt;
&lt;li&gt;تقييد صلاحيات المستخدمين والتطبيقات وفقًا لمبدأ أقل قدر من الصلاحيات.&lt;/li&gt;
&lt;li&gt;مراجعة قواعد جدران الحماية بانتظام وإزالة القواعد القديمة أو غير الضرورية.&lt;/li&gt;
&lt;li&gt;تنفيذ تقييمات أمنية دورية على الأنظمة المصرح بها للتحقق من الخدمات النشطة وسلامة إعداداتها.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;إن تطبيق هذه الممارسات لا يقتصر على حماية المنافذ فقط، بل يسهم في تعزيز أمن الشبكة والبنية التحتية التقنية بصورة عامة.&lt;/p&gt;
&lt;p&gt;تُعدّ المنافذ والبروتوكولات من المكونات الأساسية التي تتيح لشبكات الحاسوب العمل بكفاءة، إذ تساعد المنافذ على توجيه الاتصالات إلى الخدمات المناسبة، بينما تنظّم البروتوكولات عملية تبادل البيانات بين الأجهزة والتطبيقات.&lt;/p&gt;
&lt;p&gt;ولا تقتصر أهمية هذه المعرفة على الجانب النظري، بل تمتد إلى التطبيقات العملية في إدارة الشبكات، واستكشاف مشكلات الاتصال، وتحليل حركة البيانات، وتعزيز الحماية من التهديدات الأمنية.&lt;/p&gt;
&lt;p&gt;لذلك، فإن فهم المنافذ والبروتوكولات يُمثل خطوة أساسية لكل من يرغب في تطوير مهاراته في شبكات الحاسوب وإدارة الأنظمة والأمن السيبراني، ويشكّل قاعدة معرفية مهمة للانتقال إلى موضوعات أكثر تقدمًا، مثل تحليل الحزم الشبكية، وإدارة جدران الحماية، واختبار أمن الشبكات.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/4974935625500205277/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/common-network-ports-protocols.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/4974935625500205277" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/4974935625500205277" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/common-network-ports-protocols.html" rel="alternate" title="أشهر المنافذ والبروتوكولات في الشبكات" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8v1O_rFXI4YpnZ_0ZdNpvJnK_bv6w-w5i4vy6K55nz3OIC_te8eYGF7ouWjPHLtOVqNkk8StGOiawQKks2FIKA0mX5f_TjuCfyPpFMqaLRiS0vsfpk3FUSsVtmGKs02_8ngarQt7z8n-YucGTtX7ctTXlSv7FfHxcfCPCheQZzXG_rOZuAK0DSajiYu1j/s72-c/imageedit_1_6897195496.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-3639077563261998954</id><published>2026-10-24T22:19:50.975+03:00</published><updated>2026-10-24T22:19:50.975+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">دليل إعداد وتقسيم الشبكات المتقدمة Subnetting &amp; VLANs للمبتدئين</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNyBFD94kHb81c5dcWIogvsEzU2xVdUY8cP-TuF98ZQxXdz2OsitLszxKLT_Ht-qs-AGFbbm0tHHLgmKeOeCQuCvEgSh4yZbaEcW47oplvHu28cnAe81fWVSQXfciU63c8Q3DKFSdlJ7hEV8pfBz_sB5rFva-U0AXxwo-p-7MMWbxDcHj_7KFawlqrQ2hV/s640/imageedit_1_7304648358.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="دليل إعداد وتقسيم الشبكات المتقدمة (Subnetting &amp;amp; VLANs) للمبتدئين" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNyBFD94kHb81c5dcWIogvsEzU2xVdUY8cP-TuF98ZQxXdz2OsitLszxKLT_Ht-qs-AGFbbm0tHHLgmKeOeCQuCvEgSh4yZbaEcW47oplvHu28cnAe81fWVSQXfciU63c8Q3DKFSdlJ7hEV8pfBz_sB5rFva-U0AXxwo-p-7MMWbxDcHj_7KFawlqrQ2hV/s1600/imageedit_1_7304648358.webp" title="دليل إعداد وتقسيم الشبكات المتقدمة (Subnetting &amp;amp; VLANs) للمبتدئين" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;دليل إعداد وتقسيم الشبكات المتقدمة للمبتدئين&lt;/h3&gt;&lt;p&gt;يُعد تقسيم الشبكات من المهارات الأساسية التي يحتاج إليها كل من يريد تعلم إدارة الشبكات أو العمل في مجال تقنية المعلومات والأمن السيبراني. فمع زيادة عدد الأجهزة المتصلة بالشبكات، لم يعد الاعتماد على شبكة واحدة لجميع الحواسيب والطابعات والخوادم والأجهزة اللاسلكية هو الخيار الأفضل، سواء من ناحية الأداء أو التنظيم أو الأمان.&lt;/p&gt;&lt;p&gt;هنا تظهر أهمية تقنيتين أساسيتين هما &lt;strong&gt;Subnetting&lt;/strong&gt; و&lt;strong&gt;VLANs&lt;/strong&gt;. تساعد تقنية Subnetting على تقسيم نطاق عناوين IP إلى شبكات فرعية أصغر، بينما تتيح VLANs تقسيم الشبكة المحلية إلى شبكات منطقية منفصلة حتى لو كانت الأجهزة متصلة بالمحول الفيزيائي نفسه.&lt;/p&gt;&lt;p&gt;في هذا الدليل على موقع &lt;strong&gt;nusurtech.ca&lt;/strong&gt;، سنتعرف على مفهوم تقسيم الشبكات، وكيفية حساب الشبكات الفرعية، والفرق بين Subnetting وVLANs، ثم سنطبق مثالًا عمليًا على أجهزة Cisco باستخدام أوامر الإعداد والتحقق، مع شرح طريقة السماح بالاتصال بين الشبكات المختلفة واستكشاف الأخطاء الشائعة.&lt;/p&gt;&lt;h3&gt;1. ما هو Subnetting؟&lt;/h3&gt;&lt;p&gt;يشير مصطلح &lt;strong&gt;Subnetting&lt;/strong&gt; إلى تقسيم شبكة IP كبيرة إلى عدة شبكات فرعية أصغر، بحيث تحصل كل شبكة فرعية على نطاق محدد من عناوين IP.&lt;/p&gt;&lt;p&gt;على سبيل المثال، يمكن تقسيم الشبكة التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;192.168.1.0/24
&lt;/pre&gt;&lt;p&gt;إلى أربع شبكات فرعية أصغر، لكل واحدة منها نطاق عناوين مستقل.&lt;/p&gt;&lt;p&gt;يساعد هذا التقسيم على:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;تنظيم عناوين IP وتوزيعها على الأجهزة.&lt;/li&gt;&lt;li&gt;تقليل نطاق بث الرسائل داخل الشبكة الفرعية.&lt;/li&gt;&lt;li&gt;تسهيل إدارة الشبكات الكبيرة.&lt;/li&gt;&lt;li&gt;فصل مجموعات الأجهزة وفق احتياجاتها.&lt;/li&gt;&lt;li&gt;الاستفادة من عناوين IP بطريقة أكثر تنظيمًا.&lt;/li&gt;&lt;li&gt;تسهيل تطبيق سياسات التوجيه والتحكم في الوصول.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;من المهم أن تعرف أن Subnetting لا يوفر حماية كاملة بمفرده، لكنه يساعد على بناء تصميم شبكي أكثر تنظيمًا، ويمكن دمجه مع VLANs وقواعد الجدار الناري وقوائم التحكم بالوصول لتحسين الأمان.&lt;/p&gt;&lt;h3&gt;2. فهم عنوان IP وقناع الشبكة Subnet Mask&lt;/h3&gt;&lt;p&gt;يتكون عنوان IPv4 من 32 بت، ويُكتب عادةً على شكل أربعة أرقام مفصولة بنقاط، مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;192.168.1.10
&lt;/pre&gt;&lt;p&gt;يحدد قناع الشبكة (Subnet Mask) أي أجزاء من عنوان IP تمثل الشبكة وأي أجزاء تمثل الأجهزة داخلها.&lt;/p&gt;&lt;p&gt;من أقنعة الشبكات الشائعة:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;CIDR&lt;/th&gt;&lt;th&gt;Subnet Mask&lt;/th&gt;&lt;th&gt;عدد العناوين الكلي&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/24&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;256&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/25&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.128&lt;/code&gt;&lt;/td&gt;&lt;td&gt;128&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/26&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.192&lt;/code&gt;&lt;/td&gt;&lt;td&gt;64&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/27&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.224&lt;/code&gt;&lt;/td&gt;&lt;td&gt;32&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/28&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.240&lt;/code&gt;&lt;/td&gt;&lt;td&gt;16&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/29&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.248&lt;/code&gt;&lt;/td&gt;&lt;td&gt;8&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;/30&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;255.255.255.252&lt;/code&gt;&lt;/td&gt;&lt;td&gt;4&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;يشير الرقم بعد الشرطة المائلة في صيغة CIDR إلى عدد البتات المخصصة لجزء الشبكة. فمثلًا، &lt;code&gt;/24&lt;/code&gt; يعني أن 24 بت مخصصة للشبكة، وتبقى 8 بتات لجزء الأجهزة.&lt;/p&gt;&lt;p&gt;في الشبكات التقليدية التي تستخدم IPv4، يكون عدد عناوين الأجهزة القابلة للاستخدام غالبًا أقل من العدد الكلي بعنوانين، لأن أحدهما يمثل عنوان الشبكة والآخر عنوان البث (Broadcast). توجد استثناءات، مثل بعض روابط &lt;code&gt;/31&lt;/code&gt;، لذلك ينبغي مراعاة نوع الشبكة عند التصميم.&lt;/p&gt;&lt;h3&gt;3. كيف نحسب عدد الأجهزة في الشبكة الفرعية؟&lt;/h3&gt;&lt;p&gt;لحساب عدد العناوين الكلي في شبكة IPv4، نستخدم المعادلة التالية:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;عدد العناوين الكلي = 2^(عدد بتات الأجهزة)&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;وفي الشبكات الفرعية المعتادة التي تحتاج إلى عنوان شبكة وعنوان بث:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;عدد عناوين الأجهزة القابلة للاستخدام = 2^(عدد بتات الأجهزة) − 2&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنفترض أن لدينا الشبكة &lt;code&gt;192.168.1.0/26&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;بما أن عنوان IPv4 يتكون من 32 بت، فإن عدد بتات الأجهزة هو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;32 − 26 = 6
&lt;/pre&gt;&lt;p&gt;إذًا عدد العناوين الكلي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;2^6 = 64
&lt;/pre&gt;&lt;p&gt;وعدد عناوين الأجهزة القابلة للاستخدام في هذه الحالة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;64 − 2 = 62
&lt;/pre&gt;&lt;p&gt;وهذا يعني أن شبكة &lt;code&gt;/26&lt;/code&gt; توفر عادةً 62 عنوانًا للأجهزة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال عملي: تقسيم شبكة /24 إلى أربع شبكات /26&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنفترض أنك تريد تقسيم شبكة &lt;code&gt;192.168.1.0/24&lt;/code&gt; إلى أربع شبكات فرعية متساوية.&lt;/p&gt;&lt;p&gt;يمكنك استخدام قناع &lt;code&gt;/26&lt;/code&gt;، الذي يوفر 64 عنوانًا لكل شبكة. وتكون الشبكات كالتالي:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;الشبكة الفرعية&lt;/th&gt;&lt;th&gt;نطاق عناوين الأجهزة&lt;/th&gt;&lt;th&gt;عنوان البث&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;192.168.1.0/26&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.1 – 192.168.1.62&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.63&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;192.168.1.64/26&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.65 – 192.168.1.126&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.127&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;192.168.1.128/26&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.129 – 192.168.1.190&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.191&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;192.168.1.192/26&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.193 – 192.168.1.254&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.255&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;بهذا الأسلوب، أصبحت لدينا أربع شبكات منفصلة بدلًا من شبكة واحدة، مع إمكانية تخصيص كل شبكة لقسم معين داخل المؤسسة.&lt;/p&gt;&lt;p&gt;على سبيل المثال، يمكن تخصيص الشبكة الأولى للموظفين، والثانية لأجهزة الإدارة، والثالثة للخوادم، والرابعة للأجهزة الأخرى، مع مراعاة احتياجات كل قسم الفعلية.&lt;/p&gt;&lt;h3&gt;4. ما هي VLANs؟&lt;/h3&gt;&lt;p&gt;مصطلح &lt;strong&gt;VLAN&lt;/strong&gt; هو اختصار لعبارة Virtual Local Area Network، أي الشبكة المحلية الافتراضية.&lt;/p&gt;&lt;p&gt;تتيح VLAN تقسيم شبكة محلية إلى مجموعات منطقية منفصلة على مستوى الطبقة الثانية (Layer 2)، حتى عندما تكون الأجهزة متصلة بالمحول الفيزيائي نفسه.&lt;/p&gt;&lt;p&gt;على سبيل المثال، يمكن إنشاء ثلاث شبكات افتراضية داخل محول Cisco واحد:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;VLAN 10: أجهزة الموظفين.&lt;/li&gt;&lt;li&gt;VLAN 20: أجهزة الإدارة.&lt;/li&gt;&lt;li&gt;VLAN 30: الخوادم.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكن أن تكون الأجهزة متصلة بالمحول نفسه، لكن حركة البث الخاصة بكل VLAN تبقى ضمن نطاقها المنطقي، ولا تتواصل الأجهزة بين VLANs المختلفة تلقائيًا دون وجود توجيه مناسب.&lt;/p&gt;&lt;p&gt;من أهم فوائد VLANs:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;تحسين التنظيم:&lt;/strong&gt; فصل الأجهزة وفق الأقسام أو الوظائف.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تقليل نطاق البث:&lt;/strong&gt; الحد من انتشار رسائل البث داخل جميع أجزاء الشبكة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;دعم الأمان:&lt;/strong&gt; تسهيل تطبيق سياسات مختلفة على مجموعات الأجهزة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;مرونة الإدارة:&lt;/strong&gt; نقل جهاز من مجموعة منطقية إلى أخرى عبر تعديل إعداد المنفذ بدلًا من تغيير التوصيلات الفيزيائية بالضرورة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تسهيل التوسع:&lt;/strong&gt; توزيع الشبكات الافتراضية عبر المحولات المتصلة بروابط Trunk عند الحاجة.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لكن يجب الانتباه إلى أن إنشاء VLAN لا يكفي وحده لحماية الأجهزة. فإذا سمح جهاز التوجيه أو الجدار الناري بالاتصال بين VLANs دون قيود، فقد تستطيع الأجهزة الوصول إلى بعضها وفق قواعد التوجيه والسياسات المطبقة.&lt;/p&gt;&lt;h3&gt;5. الفرق بين Subnetting وVLANs&lt;/h3&gt;&lt;p&gt;على الرغم من ارتباط التقنيتين ببعضهما، فإن كل واحدة منهما تؤدي وظيفة مختلفة.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;وجه المقارنة&lt;/th&gt;&lt;th&gt;Subnetting&lt;/th&gt;&lt;th&gt;VLANs&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الوظيفة الأساسية&lt;/td&gt;&lt;td&gt;تقسيم نطاق عناوين IP إلى شبكات فرعية&lt;/td&gt;&lt;td&gt;تقسيم الشبكة المحلية منطقيًا على الطبقة الثانية&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الطبقة الأساسية&lt;/td&gt;&lt;td&gt;الطبقة الثالثة Layer 3&lt;/td&gt;&lt;td&gt;الطبقة الثانية Layer 2&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;يعتمد على&lt;/td&gt;&lt;td&gt;عنوان IP وقناع الشبكة&lt;/td&gt;&lt;td&gt;رقم VLAN وإعدادات المحولات&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;يفصل نطاقات البث؟&lt;/td&gt;&lt;td&gt;نعم، عند التعامل مع شبكات IP منفصلة&lt;/td&gt;&lt;td&gt;نعم، لكل VLAN نطاق بث مستقل&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الاتصال بين الشبكات&lt;/td&gt;&lt;td&gt;يحتاج إلى توجيه بين الشبكات&lt;/td&gt;&lt;td&gt;يحتاج إلى توجيه بين VLANs المختلفة&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الاستخدام&lt;/td&gt;&lt;td&gt;تنظيم عناوين IP وتخطيط الشبكات&lt;/td&gt;&lt;td&gt;فصل مجموعات الأجهزة داخل البنية المحلية&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;في التصميم الشائع للشبكات، يتم تخصيص شبكة IP فرعية مستقلة لكل VLAN. فمثلًا، يمكن ربط VLAN 10 بالشبكة &lt;code&gt;192.168.10.0/24&lt;/code&gt;، وربط VLAN 20 بالشبكة &lt;code&gt;192.168.20.0/24&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;هذا الربط يسهل الإدارة، لكنه لا يعني أن VLAN وSubnet هما الشيء نفسه؛ إذ إن VLAN تمثل تقسيمًا منطقيًا للطبقة الثانية، بينما تمثل Subnet تقسيمًا لعناوين الطبقة الثالثة.&lt;/p&gt;&lt;h3&gt;6. التطبيق العملي: إعداد VLANs على محول Cisco&lt;/h3&gt;&lt;p&gt;سنستخدم محول Cisco يدعم أوامر VLAN التقليدية، وننشئ شبكتين افتراضيتين:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;VLAN ID&lt;/th&gt;&lt;th&gt;الاسم&lt;/th&gt;&lt;th&gt;الشبكة المقترحة&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;SALES&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.10.0/24&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;IT&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.20.0/24&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;لنفترض أن أجهزة القسم الأول متصلة بالمنفذين &lt;code&gt;FastEthernet0/1&lt;/code&gt; و&lt;code&gt;FastEthernet0/2&lt;/code&gt;، بينما يتصل جهاز من قسم تقنية المعلومات بالمنفذ &lt;code&gt;FastEthernet0/3&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;قد تختلف أسماء المنافذ بين المحولات، لذلك استخدم أسماء الواجهات التي يدعمها جهازك.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الأولى: الدخول إلى وضع الإعداد&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;افتح واجهة سطر الأوامر CLI ونفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;enable
configure terminal
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;الخطوة الثانية: إنشاء VLAN 10 وVLAN 20&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;نفذ الأوامر التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;vlan 10
 name SALES
exit

vlan 20
 name IT
exit
&lt;/pre&gt;
&lt;p&gt;أنشأنا الآن شبكتين افتراضيتين بأرقام وأسماء واضحة، ويمكننا ربط منافذ المحول بهما.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثالثة: تعيين منافذ الأجهزة إلى VLAN 10&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;سنخصص المنفذين الأول والثاني للقسم الأول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;interface range FastEthernet0/1 - 2
 switchport mode access
 switchport access vlan 10
exit
&lt;/pre&gt;
&lt;p&gt;يعمل المنفذ من نوع Access عادةً على حمل حركة مرور VLAN واحدة غير موسومة للأجهزة الطرفية، مثل الحواسيب والطابعات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الرابعة: تعيين منفذ إلى VLAN 20&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لربط جهاز القسم الثاني بـ VLAN 20، نفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;interface FastEthernet0/3
 switchport mode access
 switchport access vlan 20
exit
&lt;/pre&gt;
&lt;p&gt;أصبح المنفذ الثالث تابعًا إلى VLAN 20.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الخامسة: التحقق من إعداد VLANs&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم الأمر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;show vlan brief
&lt;/pre&gt;
&lt;p&gt;ينبغي أن ترى VLAN 10 وVLAN 20 ضمن القائمة، وأن تظهر المنافذ التي خصصتها لكل واحدة.&lt;/p&gt;&lt;p&gt;احفظ الإعدادات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;تختلف بعض الأوامر والخصائص حسب طراز المحول وإصدار نظام التشغيل، لذا راجع وثائق الجهاز قبل تطبيقها في شبكة فعلية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;7. ما هو Access Port وما هو Trunk Port؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;عند العمل مع VLANs، ستحتاج إلى فهم نوعين مهمين من منافذ المحولات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Access Port:&lt;/strong&gt; منفذ مخصص عادةً لجهاز طرفي ضمن VLAN واحدة، مثل حاسوب أو طابعة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Trunk Port:&lt;/strong&gt; منفذ يسمح بمرور حركة مرور عدة VLANs عبر رابط واحد، مثل الرابط بين محولين أو الرابط بين محول وجهاز توجيه يدعم هذا التصميم.&lt;/p&gt;&lt;p&gt;تستخدم روابط Trunk عادةً معيار IEEE 802.1Q لتمييز حركة مرور VLANs المختلفة. وتحتاج الأجهزة المتصلة بطرفي الرابط إلى إعدادات متوافقة حتى تعمل الشبكات الافتراضية بصورة صحيحة. راجع دليل Cisco الرسمي حول &lt;a href="https://www.cisco.com/c/en/us/td/docs/switches/lan/c9000/lyr2-fwd/vlan/vlan-configuration-guide/configure-vlan-trunks.html"&gt;إعداد VLAN Trunking&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال على إعداد منفذ Trunk&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنفترض أن المنفذ &lt;code&gt;GigabitEthernet0/1&lt;/code&gt; يربط محولين، وأننا نريد السماح بمرور VLAN 10 وVLAN 20 فقط.&lt;/p&gt;&lt;p&gt;على المحول الأول، يمكن استخدام الإعداد التالي إذا كان الجهاز يدعم هذه الأوامر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;enable
configure terminal

interface GigabitEthernet0/1
 switchport mode trunk
 switchport trunk allowed vlan 10,20
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;يجب إعداد الطرف الآخر للرابط بصورة متوافقة، والتأكد من أن VLANs المطلوبة موجودة ونشطة على المحولات المعنية.&lt;/p&gt;&lt;p&gt;لا تفترض أن جميع المحولات تستخدم الأوامر نفسها؛ فبعض المنصات لها متطلبات مختلفة، وبعضها يدعم خصائص Trunking بصورة مختلفة.&lt;/p&gt;&lt;p&gt;للتحقق من حالة الرابط، استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;show interfaces trunk
&lt;/pre&gt;
&lt;p&gt;يساعدك هذا الأمر على معرفة المنافذ العاملة بوضع Trunk والشبكات الافتراضية المسموح بمرورها، وفقًا لإمكانات النظام.&lt;/p&gt;&lt;h3&gt;8. كيف نجعل VLAN 10 تتواصل مع VLAN 20؟&lt;/h3&gt;&lt;p&gt;بعد إعداد VLANs، قد تلاحظ أن الأجهزة الموجودة في VLAN 10 لا تستطيع التواصل مباشرةً مع الأجهزة الموجودة في VLAN 20. وهذا أمر متوقع؛ لأن VLANs المختلفة تمثل نطاقات منفصلة على الطبقة الثانية.&lt;/p&gt;&lt;p&gt;إذا أردنا السماح بالاتصال بينهما، نحتاج إلى &lt;strong&gt;Inter-VLAN Routing&lt;/strong&gt;، أي التوجيه بين الشبكات الافتراضية.&lt;/p&gt;&lt;p&gt;توجد طريقتان شائعتان لتنفيذ ذلك:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;استخدام جهاز توجيه Router مع رابط Trunk وتقنية Router-on-a-Stick.&lt;/li&gt;&lt;li&gt;استخدام محول من الطبقة الثالثة Layer 3 Switch مع واجهات VLAN افتراضية (SVIs).&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;في المثال التالي سنستخدم Router-on-a-Stick. افترض أن جهاز التوجيه متصل بالمحول عبر منفذ يدعم Trunk، وأن عنوان الواجهة الفيزيائية المتصلة بالمحول هو &lt;code&gt;GigabitEthernet0/0&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الأولى: إعداد منفذ المحول المتصل بالراوتر&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;افترض أن منفذ المحول المتصل بالراوتر هو &lt;code&gt;GigabitEthernet0/1&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;configure terminal

interface GigabitEthernet0/1
 switchport mode trunk
 switchport trunk allowed vlan 10,20
exit
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;الخطوة الثانية: إنشاء واجهات فرعية على الراوتر&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;على جهاز توجيه يدعم هذا الأسلوب، نفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;enable
configure terminal

interface GigabitEthernet0/0
 no shutdown
exit

interface GigabitEthernet0/0.10
 encapsulation dot1Q 10
 ip address 192.168.10.1 255.255.255.0
exit

interface GigabitEthernet0/0.20
 encapsulation dot1Q 20
 ip address 192.168.20.1 255.255.255.0
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;تمثل العناوين &lt;code&gt;192.168.10.1&lt;/code&gt; و&lt;code&gt;192.168.20.1&lt;/code&gt; البوابات الافتراضية المقترحة للأجهزة في الشبكتين.&lt;/p&gt;&lt;p&gt;تأكد من أن اسم الواجهة الفيزيائية صحيح، وأنها متصلة بمنفذ Trunk، وأن الجهاز يدعم إنشاء الواجهات الفرعية باستخدام &lt;code&gt;encapsulation dot1Q&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثالثة: ضبط أجهزة الحاسوب&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكنك استخدام الإعدادات التالية في المختبر:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;جهاز في VLAN 10: عنوان IP هو &lt;code&gt;192.168.10.10&lt;/code&gt;، وقناع الشبكة &lt;code&gt;255.255.255.0&lt;/code&gt;، والبوابة الافتراضية &lt;code&gt;192.168.10.1&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;جهاز في VLAN 20: عنوان IP هو &lt;code&gt;192.168.20.10&lt;/code&gt;، وقناع الشبكة &lt;code&gt;255.255.255.0&lt;/code&gt;، والبوابة الافتراضية &lt;code&gt;192.168.20.1&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;بعد ذلك، اختبر الاتصال بين الجهازين باستخدام الأمر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ping 192.168.20.10
&lt;/pre&gt;
&lt;p&gt;إذا كانت جميع الإعدادات صحيحة، وكان الاتصال بين VLANs مسموحًا ولا توجد قواعد تمنعه، فيُفترض أن ينجح الاختبار.&lt;/p&gt;&lt;p&gt;تذكر أن التوجيه بين VLANs لا يعني السماح بكل أنواع الاتصال تلقائيًا في جميع البيئات؛ فقد توجد قوائم تحكم بالوصول أو جدران نارية أو إعدادات أخرى تقيد حركة المرور.&lt;/p&gt;&lt;h3&gt;9. أهم أوامر التحقق واستكشاف الأخطاء&lt;/h3&gt;&lt;p&gt;عند إعداد الشبكات الفرعية وVLANs، لا يكفي إدخال الأوامر فقط. يجب التحقق من حالة المنافذ والشبكات وعناوين IP.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;الأمر&lt;/th&gt;&lt;th&gt;الوظيفة&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;show vlan brief&lt;/code&gt;&lt;/td&gt;&lt;td&gt;عرض VLANs والمنافذ التابعة لها&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;show interfaces trunk&lt;/code&gt;&lt;/td&gt;&lt;td&gt;عرض روابط Trunk وحالة الشبكات المسموح بمرورها&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;show interfaces status&lt;/code&gt;&lt;/td&gt;&lt;td&gt;مراجعة حالة المنافذ&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;show running-config&lt;/code&gt;&lt;/td&gt;&lt;td&gt;مراجعة الإعدادات الحالية&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;show ip interface brief&lt;/code&gt;&lt;/td&gt;&lt;td&gt;عرض عناوين IP وحالة الواجهات&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;show ip route&lt;/code&gt;&lt;/td&gt;&lt;td&gt;عرض جدول التوجيه على جهاز يدعم التوجيه&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;ping&lt;/code&gt;&lt;/td&gt;&lt;td&gt;اختبار إمكانية الوصول إلى عنوان آخر&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;traceroute&lt;/code&gt; أو &lt;code&gt;tracert&lt;/code&gt;&lt;/td&gt;&lt;td&gt;تتبع مسار الحزم وفق نظام التشغيل المستخدم&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;&lt;strong&gt;مشكلة عدم اتصال الأجهزة داخل VLAN نفسها&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تحقق من أن المنافذ مخصصة إلى VLAN الصحيحة، وأن الكابلات والواجهات تعمل، وأن عناوين IP وقناع الشبكة متوافقان.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مشكلة عدم اتصال VLAN 10 مع VLAN 20&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تحقق من وجود جهاز توجيه أو محول Layer 3، ومن صحة عناوين البوابات الافتراضية، ومن إعدادات الواجهات الفرعية أو واجهات SVI. افحص أيضًا رابط Trunk وتأكد من السماح بمرور VLANs المطلوبة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مشكلة عدم مرور VLAN عبر Trunk&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تحقق من أن منفذي الرابط مضبوطان بصورة متوافقة، وأن VLAN موجودة ونشطة، وأنها مسموح بها على الرابط. وإذا كان الرابط يستخدم Native VLAN مخصصة، فتأكد من تطابق إعدادها على الطرفين.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مشكلة عدم عمل عنوان IP&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تأكد من أن عنوان IP ينتمي إلى الشبكة الصحيحة، وأنه لا يتكرر مع جهاز آخر، وأن قناع الشبكة والبوابة الافتراضية مضبوطون بصورة سليمة.&lt;/p&gt;&lt;h3&gt;10. أفضل الممارسات الأمنية عند استخدام Subnetting وVLANs&lt;/h3&gt;&lt;p&gt;يساعد التصميم الجيد للشبكة على تحسين الإدارة وتقليل المخاطر، لكن يجب دمج التقسيم مع إعدادات أمنية مناسبة.&lt;/p&gt;&lt;p&gt;من أهم الممارسات:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;تخصيص VLAN منفصلة للأقسام ذات الاحتياجات المختلفة، مثل الموظفين والخوادم والضيوف والإدارة.&lt;/li&gt;&lt;li&gt;عدم السماح بالاتصال بين جميع الشبكات دون مراجعة متطلبات العمل.&lt;/li&gt;&lt;li&gt;استخدام قوائم التحكم بالوصول (ACLs) أو الجدران النارية لتقييد الاتصالات غير الضرورية.&lt;/li&gt;&lt;li&gt;تعطيل المنافذ غير المستخدمة أو وضعها في VLAN غير مخصصة للمستخدمين، وفق سياسة المؤسسة.&lt;/li&gt;&lt;li&gt;تعيين منافذ الأجهزة الطرفية إلى وضع Access صراحةً عند الحاجة، بدل تركها تعتمد على التفاوض التلقائي.&lt;/li&gt;&lt;li&gt;السماح فقط بـ VLANs المطلوبة على روابط Trunk.&lt;/li&gt;&lt;li&gt;حماية واجهات إدارة المحولات وأجهزة التوجيه.&lt;/li&gt;&lt;li&gt;توثيق خطة عناوين IP وأرقام VLANs ومنافذ المحولات.&lt;/li&gt;&lt;li&gt;الاحتفاظ بنسخة احتياطية من الإعدادات قبل التغييرات المهمة.&lt;/li&gt;&lt;li&gt;اختبار التعديلات في مختبر قبل تطبيقها على شبكة الإنتاج.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;تجنب استخدام VLAN 1 لجميع أجهزة المستخدمين دون تخطيط، ولا تعتبر تغيير رقم VLAN وحده إجراءً أمنيًا كافيًا. فالحماية الفعلية تعتمد على التصميم الكامل، وضبط الوصول، وتحديث الأجهزة، ومراقبة الشبكة.&lt;/p&gt;&lt;h3&gt;11. ما الفرق بين Subnetting وVLANs في التصميم العملي؟&lt;/h3&gt;&lt;p&gt;لنفترض أن شركة لديها ثلاثة أقسام: المبيعات، وتقنية المعلومات، والضيوف. يمكن تصميم الشبكة على النحو التالي:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;القسم&lt;/th&gt;&lt;th&gt;VLAN&lt;/th&gt;&lt;th&gt;شبكة IP&lt;/th&gt;&lt;th&gt;البوابة الافتراضية&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;المبيعات&lt;/td&gt;&lt;td&gt;10&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.10.0/24&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.10.1&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;تقنية المعلومات&lt;/td&gt;&lt;td&gt;20&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.20.0/24&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.20.1&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الضيوف&lt;/td&gt;&lt;td&gt;30&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.30.0/24&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.30.1&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;تسمح هذه الخطة بفصل الأجهزة منطقيًا، وتسهّل إدارة عناوين IP، كما توفر أساسًا لتطبيق سياسات مختلفة لكل قسم.&lt;/p&gt;&lt;p&gt;على سبيل المثال، يمكن السماح لأجهزة تقنية المعلومات بالوصول إلى واجهات إدارة الشبكة، بينما تُمنع أجهزة الضيوف من الوصول إلى الشبكات الداخلية ويُسمح لها فقط بالوصول إلى الإنترنت، وفق قواعد الجدار الناري أو قوائم التحكم بالوصول المناسبة.&lt;/p&gt;&lt;p&gt;لا بد من تنفيذ هذه السياسات فعليًا على أجهزة التوجيه أو الجدران النارية؛ فجدول VLAN وحده لا يفرض جميع قيود الاتصال المذكورة.&lt;/p&gt;&lt;p&gt;يُعد كل من &lt;strong&gt;Subnetting وVLANs&lt;/strong&gt; من المهارات الأساسية لتصميم الشبكات الحديثة وإدارتها. يساعد Subnetting على تقسيم عناوين IP إلى شبكات فرعية منظمة، بينما تتيح VLANs فصل الأجهزة منطقيًا داخل الشبكة المحلية حتى عند استخدام المحولات الفيزيائية نفسها.&lt;/p&gt;&lt;p&gt;تعلمنا في هذا الدليل كيفية فهم قناع الشبكة وحساب عدد العناوين، وتقسيم شبكة &lt;code&gt;/24&lt;/code&gt; إلى أربع شبكات &lt;code&gt;/26&lt;/code&gt;، وإنشاء VLANs على محول Cisco، وتعيين منافذ Access، وإعداد رابط Trunk، ثم تطبيق التوجيه بين VLANs باستخدام Router-on-a-Stick.&lt;/p&gt;&lt;p&gt;إذا كنت مبتدئًا، فننصحك بتجربة هذه الأوامر في Cisco Packet Tracer أو مختبر تملكه، ثم إضافة VLAN ثالثة وتطبيق سياسة تمنع شبكة الضيوف من الوصول إلى شبكة الإدارة. ستساعدك هذه التجارب على فهم العلاقة بين عناوين IP وتقسيم الطبقة الثانية والتوجيه بين الشبكات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ملاحظة:&lt;/strong&gt; قد تختلف الأوامر والخصائص المتاحة بحسب طراز أجهزة Cisco وإصدار نظام التشغيل. اختبر الإعدادات في بيئة غير إنتاجية أولًا، واحفظ نسخة من التكوين قبل إجراء تغييرات على الشبكات الفعلية.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;المصادر والمراجع&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cisco.com/c/en/us/td/docs/switches/lan/c9000/lyr2-fwd/vlan/vlan-configuration-guide/configure-vlan-trunks.html"&gt;Cisco – VLAN Configuration Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://learningnetwork.cisco.com/"&gt;Cisco Learning Network&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc4632"&gt;RFC 4632 – Classless Inter-domain Routing (CIDR)&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc1918"&gt;RFC 1918 – Address Allocation for Private Internets&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content><link href="https://www.nusurtech.ca/feeds/3639077563261998954/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/subnetting-vlans-guide-for-beginners.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/3639077563261998954" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/3639077563261998954" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/subnetting-vlans-guide-for-beginners.html" rel="alternate" title="دليل إعداد وتقسيم الشبكات المتقدمة Subnetting &amp; VLANs للمبتدئين" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNyBFD94kHb81c5dcWIogvsEzU2xVdUY8cP-TuF98ZQxXdz2OsitLszxKLT_Ht-qs-AGFbbm0tHHLgmKeOeCQuCvEgSh4yZbaEcW47oplvHu28cnAe81fWVSQXfciU63c8Q3DKFSdlJ7hEV8pfBz_sB5rFva-U0AXxwo-p-7MMWbxDcHj_7KFawlqrQ2hV/s72-c/imageedit_1_7304648358.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-5059263204301580794</id><published>2026-10-23T16:12:27.972+03:00</published><updated>2026-10-23T16:13:31.441+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">شرح بروتوكول OSPF وكيفية ضبطه على أجهزة سيسكو Cisco</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv2mGewXsg_VVmEzhi60yMLDgyi1z2tzftkYCzoKWVQvPz8digi71ErZoGdms7zCtWhi7PNgGodDHkGkgAr-ZG5qdW7aTvzxruvAzj89XDQX84N_bcq7PhF5TWjQIGEEwOtJIMXxHZP839Q8aQiAxRPWJ5lI5JDguXYBzYX1byxHvFzdk4kkxd5ZPuFF9X/s640/imageedit_3_4553798800.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="شرح بروتوكول OSPF وكيفية ضبطه على أجهزة Cisco step-by-step" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv2mGewXsg_VVmEzhi60yMLDgyi1z2tzftkYCzoKWVQvPz8digi71ErZoGdms7zCtWhi7PNgGodDHkGkgAr-ZG5qdW7aTvzxruvAzj89XDQX84N_bcq7PhF5TWjQIGEEwOtJIMXxHZP839Q8aQiAxRPWJ5lI5JDguXYBzYX1byxHvFzdk4kkxd5ZPuFF9X/s1600/imageedit_3_4553798800.webp" title="شرح بروتوكول OSPF وكيفية ضبطه على أجهزة Cisco step-by-step" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;شرح بروتوكول OSPF وكيفية ضبطه على أجهزة Cisco&lt;/h3&gt;&lt;p&gt;يُعد بروتوكول &lt;strong&gt;OSPF (Open Shortest Path First)&lt;/strong&gt; من أهم بروتوكولات التوجيه الديناميكي المستخدمة في شبكات الحاسوب، حيث يساعد أجهزة التوجيه (Routers) على اكتشاف الشبكات المختلفة وتبادل معلومات التوجيه واختيار المسارات المناسبة لنقل البيانات. ويُستخدم OSPF على نطاق واسع في شبكات الشركات والمؤسسات ومراكز البيانات، لما يوفره من سرعة في التقارب وقابلية للتوسع ودعم لتصميمات الشبكات الكبيرة.&lt;/p&gt;&lt;p&gt;إذا كنت تتعلم الشبكات باستخدام أجهزة Cisco أو تستعد للحصول على شهادة CCNA، فإن فهم OSPF وتطبيقه عمليًا من المهارات الأساسية التي تحتاج إليها. ففي حين يتطلب التوجيه الثابت (Static Routing) إضافة المسارات يدويًا، يستطيع OSPF تبادل معلومات الشبكة تلقائيًا مع أجهزة التوجيه المجاورة، ثم حساب أفضل المسارات اعتمادًا على تكلفة المسار.&lt;/p&gt;&lt;p&gt;في هذا الدرس على موقع &lt;strong&gt;nusurtech.ca&lt;/strong&gt;، سنتعرف على مفهوم OSPF وآلية عمله، والفرق بينه وبين بروتوكولات التوجيه الأخرى، ثم سننفذ إعدادًا عمليًا على ثلاثة أجهزة Cisco خطوة بخطوة، مع أوامر التحقق من الاتصال وحل المشكلات الشائعة.&lt;/p&gt;&lt;h3&gt;ما هو بروتوكول OSPF؟&lt;/h3&gt;&lt;p&gt;OSPF هو اختصار لعبارة &lt;strong&gt;Open Shortest Path First&lt;/strong&gt;، وهو بروتوكول توجيه ديناميكي داخلي (IGP) يُستخدم لتبادل معلومات التوجيه بين أجهزة التوجيه داخل النظام المستقل (Autonomous System).&lt;/p&gt;&lt;p&gt;يعتمد OSPF على خوارزمية &lt;strong&gt;Dijkstra Shortest Path First (SPF)&lt;/strong&gt; لحساب أقصر المسارات وفقًا لتكلفة كل مسار. ولا تعني كلمة «أقصر» بالضرورة أقل مسافة جغرافية أو أقل عدد من أجهزة التوجيه، بل تشير إلى المسار الذي يحقق أقل مجموع من تكاليف OSPF.&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا كان لدينا ثلاثة أجهزة توجيه تربط بين شبكة المصدر وشبكة الوجهة، فقد يختار OSPF مسارًا يمر عبر جهازين بدلًا من مسار يمر عبر جهاز واحد، إذا كانت التكلفة الإجمالية للمسار الأول أقل.&lt;/p&gt;&lt;p&gt;ومن أهم خصائص OSPF:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;بروتوكول توجيه ديناميكي يتكيف مع تغييرات الشبكة.&lt;/li&gt;&lt;li&gt;يعتمد على حالة الروابط (Link-State) بدلًا من الاعتماد فقط على المسارات التي يعلنها الجيران.&lt;/li&gt;&lt;li&gt;يستخدم خوارزمية SPF لحساب المسارات.&lt;/li&gt;&lt;li&gt;يدعم تقسيم الشبكة إلى مناطق (Areas) لتحسين قابلية التوسع.&lt;/li&gt;&lt;li&gt;يدعم التوجيه عديم الفئات (CIDR) والشبكات ذات الأقنعة المختلفة.&lt;/li&gt;&lt;li&gt;يستطيع دعم موازنة الحمل عبر مسارات متساوية التكلفة، وفقًا لإعدادات الجهاز.&lt;/li&gt;&lt;li&gt;يستخدم المقياس المعروف باسم Cost لاختيار المسارات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;كيف يعمل بروتوكول OSPF؟&lt;/h3&gt;&lt;p&gt;يعمل OSPF من خلال مجموعة من المراحل التي تتيح لأجهزة التوجيه التعرف على بعضها وتكوين صورة عن بنية الشبكة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;1. اكتشاف الأجهزة المجاورة (Neighbor Discovery)&lt;/h4&gt;&lt;p&gt;يرسل جهاز التوجيه رسائل Hello عبر الواجهات التي تم تفعيل OSPF عليها، بهدف اكتشاف أجهزة التوجيه الأخرى التي تستخدم البروتوكول نفسه على الشبكة.&lt;/p&gt;&lt;p&gt;عندما تتوافق المعلمات المطلوبة بين الأجهزة، يمكن أن تتكون علاقة جوار (Neighbor Relationship). وتشمل المعلمات المهمة، بحسب نوع الشبكة والإعدادات، منطقة OSPF، ومؤقتات Hello وDead، وإعدادات المصادقة، وقناع الشبكة في بعض أنواع الشبكات.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;2. تكوين علاقات الجوار&lt;/h4&gt;&lt;p&gt;بعد اكتشاف الأجهزة، يحاول OSPF بناء علاقة جوار معها. وعلى شبكات Ethernet متعددة الوصول، قد ينتخب البروتوكول جهازًا معينًا باسم DR (Designated Router) وجهازًا احتياطيًا باسم BDR لتقليل عدد تبادلات معلومات حالة الروابط.&lt;/p&gt;&lt;p&gt;ليس من الضروري أن تمر كل علاقة جوار عبر حالة Full في جميع أنواع الشبكات؛ فالعلاقات بين بعض الأجهزة على شبكات Broadcast قد تتوقف عند حالات معينة وفق دور DR وBDR.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;3. تبادل معلومات حالة الروابط&lt;/h4&gt;&lt;p&gt;يتبادل الجيران إعلانات حالة الروابط المعروفة باسم LSA (Link-State Advertisements). وتُستخدم هذه المعلومات لبناء قاعدة بيانات حالة الروابط (Link-State Database أو LSDB).&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;4. حساب أفضل المسارات&lt;/h4&gt;&lt;p&gt;بعد جمع معلومات الشبكة، يشغّل OSPF خوارزمية SPF لحساب أفضل المسارات من وجهة نظر جهاز التوجيه الحالي.&lt;/p&gt;&lt;p&gt;تُضاف المسارات المناسبة إلى جدول التوجيه، ويمكن أن تتغير النتائج عندما تتغير حالة رابط أو تظهر معلومات جديدة عن الشبكة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;5. التكيف مع تغييرات الشبكة&lt;/h4&gt;&lt;p&gt;إذا تعطل رابط أو تغيرت بنية الشبكة، يعلن OSPF عن التغيير وينفذ الحسابات اللازمة للوصول إلى مسارات بديلة، إذا كانت متاحة.&lt;/p&gt;&lt;p&gt;تُعرف المدة اللازمة حتى تتفق أجهزة التوجيه على معلومات التوجيه الجديدة باسم التقارب (Convergence)، وتتأثر بسرعة اكتشاف العطل وطبيعة الشبكة وإعدادات البروتوكول وأداء الأجهزة.&lt;/p&gt;&lt;h3&gt;ما هي مناطق OSPF (OSPF Areas)؟&lt;/h3&gt;&lt;p&gt;يدعم OSPF تقسيم الشبكة إلى مناطق منطقية تسمى Areas، بهدف تقليل تعقيد قاعدة بيانات حالة الروابط وتحسين قابلية التوسع.&lt;/p&gt;&lt;p&gt;تُعرف المنطقة الأساسية باسم &lt;strong&gt;Area 0&lt;/strong&gt; أو Backbone Area، وهي المنطقة المحورية في تصميمات OSPF متعددة المناطق. ويجب أن ترتبط المناطق غير الأساسية بالمنطقة 0 وفق التصميم الصحيح، مع وجود استثناءات وحلول خاصة لبعض حالات الربط.&lt;/p&gt;&lt;p&gt;في الشبكات الصغيرة، يمكنك تشغيل OSPF داخل منطقة واحدة، مثل Area 0، وهذا ما سنستخدمه في التطبيق العملي التالي.&lt;/p&gt;&lt;p&gt;من المصطلحات المهمة أيضًا:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;Internal Router:&lt;/strong&gt; جهاز توجيه تقع جميع واجهاته المشاركة في OSPF ضمن المنطقة نفسها.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Backbone Router:&lt;/strong&gt; جهاز توجيه لديه واجهة مشاركة في Area 0.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ABR (Area Border Router):&lt;/strong&gt; جهاز يربط بين منطقتين أو أكثر من مناطق OSPF، إحداها عادةً Area 0.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ASBR (Autonomous System Boundary Router):&lt;/strong&gt; جهاز يحقن مسارات من مصادر توجيه خارجية إلى OSPF.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;ضبط OSPF على أجهزة Cisco خطوة بخطوة&lt;/h3&gt;&lt;p&gt;سنستخدم ثلاثة أجهزة توجيه Cisco، ونفترض أن جميعها تعمل بإصدار Cisco IOS يدعم أوامر OSPF التقليدية باستخدام &lt;code&gt;router ospf&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;سننشئ شبكة بسيطة تتصل فيها ثلاثة أجهزة توجيه على التوالي، ثم نفعّل OSPF لتتمكن الشبكات المتصلة بها من التواصل عبر التوجيه الديناميكي.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;أولًا: تصميم الشبكة&lt;/h4&gt;&lt;p&gt;سيكون لدينا المخطط التالي:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;PC1 — R1 — R2 — R3 — PC3&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;سنستخدم الشبكات التالية في المثال:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;الرابط أو الجهاز&lt;/th&gt;&lt;th&gt;عنوان الشبكة أو الواجهة&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;شبكة LAN الخاصة بـ R1&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.0/24&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الرابط بين R1 وR2&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.0.12.0/30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;الرابط بين R2 وR3&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.0.23.0/30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;شبكة LAN الخاصة بـ R3&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.3.0/24&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;عناوين الواجهات ستكون كما يلي:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;الجهاز&lt;/th&gt;&lt;th&gt;الواجهة&lt;/th&gt;&lt;th&gt;عنوان IP&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;R1&lt;/td&gt;&lt;td&gt;G0/0&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.1.1/24&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;R1&lt;/td&gt;&lt;td&gt;G0/1&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.0.12.1/30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;R2&lt;/td&gt;&lt;td&gt;G0/0&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.0.12.2/30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;R2&lt;/td&gt;&lt;td&gt;G0/1&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.0.23.1/30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;R3&lt;/td&gt;&lt;td&gt;G0/0&lt;/td&gt;&lt;td&gt;&lt;code&gt;10.0.23.2/30&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;R3&lt;/td&gt;&lt;td&gt;G0/1&lt;/td&gt;&lt;td&gt;&lt;code&gt;192.168.3.1/24&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;قد تختلف أسماء الواجهات بين الأجهزة، مثل &lt;code&gt;GigabitEthernet0/0&lt;/code&gt; أو &lt;code&gt;GigabitEthernet0/0/0&lt;/code&gt;. استخدم أسماء الواجهات الفعلية التي تظهر في جهازك.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ثانيًا: ضبط عناوين IP على الراوتر R1&lt;/h4&gt;&lt;p&gt;ادخل إلى وضع الإعدادات باستخدام الأوامر التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
enable
configure terminal
&lt;/pre&gt;
&lt;p&gt;اضبط واجهة LAN والواجهة المتصلة بـ R2:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
interface GigabitEthernet0/0
 ip address 192.168.1.1 255.255.255.0
 no shutdown
exit

interface GigabitEthernet0/1
 ip address 10.0.12.1 255.255.255.252
 no shutdown
exit
&lt;/pre&gt;
&lt;p&gt;احفظ الإعدادات بعد التأكد من صحتها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
end
copy running-config startup-config
&lt;/pre&gt;
&lt;h4 style="text-align: right;"&gt;ثالثًا: ضبط عناوين IP على الراوتر R2&lt;/h4&gt;&lt;p&gt;نفذ الإعدادات التالية على الجهاز R2:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
enable
configure terminal

interface GigabitEthernet0/0
 ip address 10.0.12.2 255.255.255.252
 no shutdown
exit

interface GigabitEthernet0/1
 ip address 10.0.23.1 255.255.255.252
 no shutdown
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;تأكد من أن الواجهات تعمل وأن عناوين IP تقع ضمن الشبكات الصحيحة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;رابعًا: ضبط عناوين IP على الراوتر R3&lt;/h4&gt;&lt;p&gt;على الجهاز R3، استخدم الأوامر التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
enable
configure terminal

interface GigabitEthernet0/0
 ip address 10.0.23.2 255.255.255.252
 no shutdown
exit

interface GigabitEthernet0/1
 ip address 192.168.3.1 255.255.255.0
 no shutdown
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;قبل الانتقال إلى OSPF، تحقق من حالة الواجهات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip interface brief
&lt;/pre&gt;
&lt;p&gt;يُفترض أن تظهر الواجهات المطلوبة بالحالة &lt;code&gt;up/up&lt;/code&gt; إذا كانت التوصيلات والإعدادات سليمة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;خامسًا: تفعيل OSPF على الراوتر R1&lt;/h4&gt;&lt;p&gt;الآن سنبدأ تفعيل بروتوكول OSPF. سنستخدم رقم العملية (Process ID) وهو &lt;code&gt;1&lt;/code&gt;، ونفعّل الإعلان عن الشبكتين المتصلتين بـ R1 داخل Area 0.&lt;/p&gt;&lt;p&gt;نفذ الأوامر التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
enable
configure terminal

router ospf 1
 router-id 1.1.1.1
 network 192.168.1.0 0.0.0.255 area 0
 network 10.0.12.0 0.0.0.3 area 0
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;شرح الأوامر:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;code&gt;router ospf 1&lt;/code&gt;: ينشئ عملية OSPF برقم 1 على الجهاز.&lt;/li&gt;&lt;li&gt;&lt;code&gt;router-id 1.1.1.1&lt;/code&gt;: يحدد معرّفًا فريدًا لهذا الراوتر داخل نطاق OSPF.&lt;/li&gt;&lt;li&gt;&lt;code&gt;network&lt;/code&gt;: يحدد الواجهات التي ستشارك في OSPF وفق مطابقة عنوان الواجهة مع عنوان الشبكة وقناع Wildcard.&lt;/li&gt;&lt;li&gt;&lt;code&gt;area 0&lt;/code&gt;: يضع الواجهات المطابقة في المنطقة الأساسية.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لاحظ أن رقم العملية &lt;code&gt;1&lt;/code&gt; محلي على الجهاز، ولا يشترط أن يكون متطابقًا بين جميع أجهزة التوجيه المتجاورة. أما إعدادات المنطقة على الروابط المشتركة فيجب أن تتوافق حتى تتكون علاقة الجوار بصورة صحيحة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;سادسًا: تفعيل OSPF على الراوتر R2&lt;/h4&gt;&lt;p&gt;يجب أن يعلن R2 عن الشبكتين اللتين تتصل بهما واجهتاه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
enable
configure terminal

router ospf 1
 router-id 2.2.2.2
 network 10.0.12.0 0.0.0.3 area 0
 network 10.0.23.0 0.0.0.3 area 0
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;يعمل R2 هنا كحلقة وصل بين R1 وR3. وعند نجاح تكوين الجوار، سيتبادل معلومات التوجيه مع الجهازين، ثم يتعلم الشبكات التي لا تتصل به مباشرةً.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;سابعًا: تفعيل OSPF على الراوتر R3&lt;/h4&gt;&lt;p&gt;نفذ الأوامر التالية على R3:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
enable
configure terminal

router ospf 1
 router-id 3.3.3.3
 network 10.0.23.0 0.0.0.3 area 0
 network 192.168.3.0 0.0.0.255 area 0
exit

end
copy running-config startup-config
&lt;/pre&gt;
&lt;p&gt;بهذا نكون قد فعّلنا OSPF على الأجهزة الثلاثة. إذا كانت عناوين IP والتوصيلات وإعدادات المنطقة صحيحة، فسيتمكن R1 من تعلم شبكة &lt;code&gt;192.168.3.0/24&lt;/code&gt; من خلال R2، وسيتمكن R3 من تعلم شبكة &lt;code&gt;192.168.1.0/24&lt;/code&gt;.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ثامنًا: ما هو Wildcard Mask في OSPF؟&lt;/h4&gt;&lt;p&gt;من المهم فهم قيمة Wildcard Mask التي استخدمناها في أوامر &lt;code&gt;network&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;قناع Wildcard هو معكوس قناع الشبكة الفرعية (Subnet Mask)، ويستخدم في إعداد OSPF التقليدي لتحديد الواجهات التي ستطابقها أوامر &lt;code&gt;network&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;أمثلة:&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;Subnet Mask&lt;/th&gt;&lt;th&gt;Wildcard Mask&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;255.255.255.0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;0.0.0.255&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;255.255.255.252&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;0.0.0.3&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;255.255.0.0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;0.0.255.255&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code&gt;255.0.0.0&lt;/code&gt;&lt;/td&gt;&lt;td&gt;&lt;code&gt;0.255.255.255&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;على سبيل المثال:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;network 10.0.12.0 0.0.0.3 area 0&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;يعني أن الواجهات التي تقع عناوينها ضمن النطاق المطابق للشبكة &lt;code&gt;10.0.12.0/30&lt;/code&gt; ستُفعّل عليها عملية OSPF ضمن Area 0.&lt;/p&gt;&lt;p&gt;ومن المهم معرفة أن أمر &lt;code&gt;network&lt;/code&gt; في OSPF التقليدي لا يضيف الشبكة إلى جدول التوجيه كما يفعل مسار ثابت؛ بل يحدد الواجهات التي سيعمل عليها OSPF، ومن خلالها تُعلن الشبكات المتصلة بها وفق حالة الواجهات وإعدادات البروتوكول.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;تاسعًا: التحقق من أن OSPF يعمل بشكل صحيح&lt;/h4&gt;&lt;p&gt;بعد الانتهاء من الإعدادات، لا تفترض أن البروتوكول يعمل لمجرد قبول الراوتر للأوامر. يجب فحص حالة الجوار وجدول التوجيه وقاعدة بيانات OSPF.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. عرض جيران OSPF&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;نفذ الأمر التالي على كل جهاز:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip ospf neighbor
&lt;/pre&gt;
&lt;p&gt;على R1، من المتوقع ظهور R2 كجار. وعلى R2، من المتوقع ظهور كل من R1 وR3، وعلى R3، من المتوقع ظهور R2.&lt;/p&gt;&lt;p&gt;على روابط Ethernet بين جهازين فقط، قد تظهر حالة الجوار &lt;code&gt;FULL/DR&lt;/code&gt; أو &lt;code&gt;FULL/BDR&lt;/code&gt; أو &lt;code&gt;FULL/-&lt;/code&gt; بحسب نوع الواجهة وطريقة تمثيلها. الأهم هو التأكد من اكتمال علاقة الجوار، مع مراعاة نوع الشبكة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. عرض المسارات المكتسبة من OSPF&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip route ospf
&lt;/pre&gt;
&lt;p&gt;على R1، ينبغي أن يظهر مسار إلى الشبكة &lt;code&gt;192.168.3.0/24&lt;/code&gt; إذا نجح تبادل معلومات التوجيه.&lt;/p&gt;&lt;p&gt;قد يظهر المسار بصيغة مشابهة لما يلي، مع اختلاف التفاصيل والتكلفة بحسب المنصة والإعدادات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
O 192.168.3.0/24 [110/...] via 10.0.12.2
&lt;/pre&gt;
&lt;p&gt;يشير الحرف &lt;code&gt;O&lt;/code&gt; إلى أن المسار تم تعلمه عبر OSPF، بينما تمثل القيمة &lt;code&gt;110&lt;/code&gt; المسافة الإدارية الافتراضية لـ OSPF على Cisco IOS. أما التكلفة فتتغير بحسب الواجهات وإعدادات البروتوكول.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. عرض جدول التوجيه كاملًا&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip route
&lt;/pre&gt;
&lt;p&gt;يعرض هذا الأمر الشبكات المتصلة مباشرةً والمسارات الثابتة والديناميكية الموجودة في جدول التوجيه.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. عرض إعدادات OSPF&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip protocols
&lt;/pre&gt;
&lt;p&gt;يساعدك هذا الأمر على مراجعة بروتوكولات التوجيه الفعالة، ومعرّف العملية، ومعلومات OSPF، والشبكات التي يجري الإعلان عنها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5. عرض معلومات العملية&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip ospf
&lt;/pre&gt;
&lt;p&gt;يعرض معلومات عامة عن عملية OSPF، مثل معرّف الراوتر والمنطقة وإحصاءات البروتوكول.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;عاشرًا: اختبار الاتصال باستخدام Ping&lt;/h4&gt;&lt;p&gt;بعد التأكد من ظهور الجيران والمسارات، انتقل إلى اختبار الاتصال بين الشبكات.&lt;/p&gt;&lt;p&gt;إذا كانت لديك أجهزة حاسوب موصولة بشبكتي LAN، اضبط مثلًا:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;PC1: العنوان &lt;code&gt;192.168.1.10/24&lt;/code&gt; والبوابة الافتراضية &lt;code&gt;192.168.1.1&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;PC3: العنوان &lt;code&gt;192.168.3.10/24&lt;/code&gt; والبوابة الافتراضية &lt;code&gt;192.168.3.1&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ثم نفذ من PC1:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
ping 192.168.3.10
&lt;/pre&gt;
&lt;p&gt;إذا كانت جميع الإعدادات صحيحة، فيُفترض أن يتمكن PC1 من الوصول إلى PC3 عبر R1 ثم R2 ثم R3.&lt;/p&gt;&lt;p&gt;قد يفشل أول اختبار Ping أحيانًا بسبب عملية اكتشاف عناوين الطبقة الثانية أو تجهيز المسارات. أعد الاختبار بعد التأكد من اكتمال الجوار والمسارات.&lt;/p&gt;&lt;p&gt;وإذا لم ينجح الاتصال، فلا تكتفِ بتعديل OSPF مباشرةً؛ تحقق أولًا من عناوين الأجهزة والبوابات الافتراضية وحالة الواجهات وقواعد جدار الحماية.&lt;/p&gt;&lt;h3&gt;كيف تختار أفضل مسار في OSPF؟&lt;/h3&gt;&lt;p&gt;يستخدم OSPF قيمة Cost لتحديد المسار المفضل. وفي تطبيقات Cisco IOS الشائعة، تعتمد التكلفة الافتراضية على عرض النطاق الترددي للواجهة مقارنةً بقيمة مرجعية، مع اختلاف الإعدادات والتفاصيل حسب المنصة.&lt;/p&gt;&lt;p&gt;يمكن عرض تكلفة واجهة باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip ospf interface
&lt;/pre&gt;
&lt;p&gt;ويمكنك مراجعة إعدادات واجهة معينة لتحديد خصائصها، بما في ذلك عرض النطاق الذي قد يؤثر في حساب التكلفة.&lt;/p&gt;&lt;p&gt;إذا توفر مساران متساويا التكلفة إلى الوجهة، فقد يستطيع OSPF إدراجهما معًا في جدول التوجيه وفق إعدادات الجهاز. ويُعرف ذلك باسم Equal-Cost Multi-Path (ECMP).&lt;/p&gt;&lt;p&gt;لا تغيّر قيمة التكلفة لمجرد جعل رقمها أقل؛ بل صمّمها بما يتوافق مع سعة الروابط وسياسة التوجيه المطلوبة، ثم اختبر أثر التغيير.&lt;/p&gt;&lt;h3&gt;حل أشهر مشكلات OSPF على أجهزة Cisco&lt;/h3&gt;&lt;p&gt;قد تواجه بعض المشكلات بعد إعداد OSPF. إليك أهم الأسباب التي ينبغي التحقق منها:&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;المشكلة الأولى: عدم ظهور الجار في show ip ospf neighbor&lt;/h4&gt;&lt;p&gt;الأسباب المحتملة تشمل:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;واجهة متوقفة أو كابل غير متصل.&lt;/li&gt;&lt;li&gt;تفعيل OSPF على واجهة غير صحيحة.&lt;/li&gt;&lt;li&gt;عدم تطابق منطقة OSPF على الرابط.&lt;/li&gt;&lt;li&gt;اختلاف مؤقتات Hello وDead.&lt;/li&gt;&lt;li&gt;عدم تطابق إعدادات المصادقة.&lt;/li&gt;&lt;li&gt;استخدام أقنعة أو إعدادات شبكية غير مناسبة لنوع الشبكة.&lt;/li&gt;&lt;li&gt;وجود قوائم تحكم أو إعدادات تمنع تبادل حزم OSPF.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ابدأ بالأوامر التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip interface brief
show ip ospf interface
show ip protocols
show ip ospf neighbor
&lt;/pre&gt;
&lt;p&gt;تحقق من الواجهات وعناوين IP، ثم راجع إعدادات المنطقة والمؤقتات والمصادقة عند استخدامها.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;المشكلة الثانية: ظهور الجيران ولكن عدم وجود المسار المطلوب&lt;/h4&gt;&lt;p&gt;إذا ظهرت علاقة الجوار، لكن المسار إلى شبكة بعيدة غير موجود، فتأكد من أن الشبكة المطلوبة متصلة بواجهة فعالة ومشمولة في إعداد OSPF، وأن الواجهة ليست مستبعدة من الإعلان، وأن المسار يُعلن ضمن المنطقة الصحيحة.&lt;/p&gt;&lt;p&gt;يمكنك مراجعة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show ip route
show ip route ospf
show ip ospf database
&lt;/pre&gt;
&lt;p&gt;تأكد أيضًا من أن عنوان الشبكة وقناع Wildcard في أوامر &lt;code&gt;network&lt;/code&gt; صحيحان، وأنه لا توجد إعدادات أخرى تؤثر في إعلان المسار.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;المشكلة الثالثة: ظهور الواجهات بحالة down/down أو up/down&lt;/h4&gt;&lt;p&gt;إذا كانت الواجهة &lt;code&gt;down/down&lt;/code&gt;، فتحقق من الكابل أو الاتصال الفعلي أو حالة الطرف الآخر. أما &lt;code&gt;up/down&lt;/code&gt; فقد يشير إلى مشكلة في بروتوكول الواجهة أو في الطرف المقابل أو في نوع الاتصال.&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
show interfaces
show ip interface brief
&lt;/pre&gt;
&lt;p&gt;ولا تنسَ أن أمر &lt;code&gt;no shutdown&lt;/code&gt; مطلوب على الواجهات التي تكون مغلقة إداريًا.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;المشكلة الرابعة: اختلاف Router ID أو تغييره&lt;/h4&gt;&lt;p&gt;يجب أن يكون لكل جهاز توجيه Router ID فريد داخل نطاق OSPF. استخدم معرفات مختلفة بوضوح، مثل &lt;code&gt;1.1.1.1&lt;/code&gt; و&lt;code&gt;2.2.2.2&lt;/code&gt; و&lt;code&gt;3.3.3.3&lt;/code&gt; في المختبر.&lt;/p&gt;&lt;p&gt;إذا غيرت Router ID بعد بدء عملية OSPF، فقد لا يسري التغيير فورًا في بعض إصدارات IOS دون إعادة تشغيل العملية أو إعادة تحميل الجهاز. قبل تنفيذ أي إجراء يؤثر في عملية التوجيه، راجع أثره على الشبكة، خاصة في بيئة الإنتاج.&lt;/p&gt;&lt;h3&gt;أفضل الممارسات الأمنية عند تشغيل OSPF&lt;/h3&gt;&lt;p&gt;لا يكفي أن يعمل التوجيه بصورة صحيحة؛ فمن الضروري أيضًا حماية بيئة الشبكة من التكوينات غير المقصودة أو محاولات التلاعب بمعلومات التوجيه.&lt;/p&gt;&lt;p&gt;من أفضل الممارسات:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;تفعيل OSPF فقط على الواجهات التي تحتاج إلى تبادل معلومات التوجيه.&lt;/li&gt;&lt;li&gt;استخدام إعدادات المصادقة المناسبة عندما تدعمها المنصة والتصميم.&lt;/li&gt;&lt;li&gt;ضبط الواجهات المتصلة بشبكات المستخدمين كواجهات Passive عند الحاجة، حتى لا تحاول تكوين علاقات جوار مع أجهزة غير موثوقة، مع مراعاة أن الشبكة المتصلة قد تظل معلنة عبر OSPF.&lt;/li&gt;&lt;li&gt;تقييد الوصول الإداري إلى أجهزة التوجيه.&lt;/li&gt;&lt;li&gt;توثيق إعدادات OSPF ومراجعتها دوريًا.&lt;/li&gt;&lt;li&gt;حفظ نسخ احتياطية من إعدادات الأجهزة قبل التغييرات المهمة.&lt;/li&gt;&lt;li&gt;اختبار أي تغيير في مختبر أو بيئة غير إنتاجية عندما يكون ذلك ممكنًا.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكنك عادةً ضبط واجهة LAN كواجهة Passive ضمن عملية OSPF، مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
router ospf 1
 passive-interface GigabitEthernet0/0
 &lt;/pre&gt;
&lt;p&gt;هذا المثال يفترض أن الواجهة المذكورة هي واجهة LAN ولا تحتاج إلى تكوين جيران OSPF عليها. يجب تعديل اسم الواجهة بما يتناسب مع جهازك.&lt;/p&gt;&lt;p&gt;يُعد بروتوكول OSPF من أهم بروتوكولات التوجيه الديناميكي التي يجب على كل مهتم بالشبكات إتقانها. فهو يتيح لأجهزة التوجيه تبادل معلومات الشبكة، وبناء قاعدة بيانات لحالة الروابط، وحساب أفضل المسارات باستخدام خوارزمية SPF.&lt;/p&gt;&lt;p&gt;في هذا الدرس، تعرفنا على مفهوم OSPF ومناطق التوجيه، ثم أنشأنا إعدادًا عمليًا على ثلاثة أجهزة Cisco، وضبطنا عناوين IP، وفعّلنا OSPF باستخدام أوامر &lt;code&gt;router ospf&lt;/code&gt; و&lt;code&gt;network&lt;/code&gt;، ثم تحققنا من الجيران والمسارات واختبرنا الاتصال باستخدام Ping.&lt;/p&gt;&lt;p&gt;إذا كنت تتدرب على Cisco Packet Tracer أو أجهزة حقيقية ضمن مختبر مصرح به، فحاول إعادة تنفيذ الخطوات بنفسك، ثم غيّر عناوين الشبكات أو أضف راوترًا رابعًا وراقب كيف يتعلم OSPF المسارات الجديدة.&lt;/p&gt;&lt;p&gt;تذكّر أن إتقان OSPF لا يعتمد على حفظ الأوامر فقط، بل على فهم كيفية عمل الجوار، وكيفية إعلان الشبكات، وكيفية قراءة جدول التوجيه واستكشاف المشكلات بصورة منهجية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ملاحظة:&lt;/strong&gt; قد تختلف أسماء الواجهات وبعض الأوامر المتاحة بحسب طراز جهاز Cisco وإصدار IOS أو IOS XE. نفّذ التغييرات على أجهزة تملكها أو لديك تصريح بإدارتها، وخذ نسخة احتياطية من الإعدادات قبل تعديل شبكات الإنتاج.&lt;/p&gt;&lt;h3&gt;المصادر والمراجع&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.cisco.com/"&gt;Cisco – OSPF Configuration Guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://learningnetwork.cisco.com/"&gt;Cisco Learning Network&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc2328"&gt;RFC 2328 – OSPF Version 2&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content><link href="https://www.nusurtech.ca/feeds/5059263204301580794/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/ospf-configuration-cisco-step-by-step.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5059263204301580794" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5059263204301580794" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/ospf-configuration-cisco-step-by-step.html" rel="alternate" title="شرح بروتوكول OSPF وكيفية ضبطه على أجهزة سيسكو Cisco" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgv2mGewXsg_VVmEzhi60yMLDgyi1z2tzftkYCzoKWVQvPz8digi71ErZoGdms7zCtWhi7PNgGodDHkGkgAr-ZG5qdW7aTvzxruvAzj89XDQX84N_bcq7PhF5TWjQIGEEwOtJIMXxHZP839Q8aQiAxRPWJ5lI5JDguXYBzYX1byxHvFzdk4kkxd5ZPuFF9X/s72-c/imageedit_3_4553798800.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-5462493043378551107</id><published>2026-10-22T21:18:40.764+03:00</published><updated>2026-10-22T21:18:40.764+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="احتراف الأمن السيبراني"/><title type="text">أفضل أدوات فحص الثغرات للشبكات</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKyXL8B7Kvfzuc_RZLEpv85sy-8_wz10_5ZGjjJEgoYLfIXnB-OE3CZ8sSyzrNWhiTvxJz2y7L5vT7dgTQZOkiFnhnzHhKa5SehJzAiHxc9fZVkk3Oyj2UqOkiuAIN0e5mlrf4nX-u_nsjn_XzJudoTLx4PrfNmLFi3z72dXcSwn2mP2bhyphenhyphen6T2sxZRMRhK/s640/imageedit_1_4171208420.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="أفضل أدوات فحص وفحص الثغرات (Vulnerability Assessment Tools) للشبكات" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKyXL8B7Kvfzuc_RZLEpv85sy-8_wz10_5ZGjjJEgoYLfIXnB-OE3CZ8sSyzrNWhiTvxJz2y7L5vT7dgTQZOkiFnhnzHhKa5SehJzAiHxc9fZVkk3Oyj2UqOkiuAIN0e5mlrf4nX-u_nsjn_XzJudoTLx4PrfNmLFi3z72dXcSwn2mP2bhyphenhyphen6T2sxZRMRhK/s1600/imageedit_1_4171208420.webp" title="أفضل أدوات فحص وفحص الثغرات (Vulnerability Assessment Tools) للشبكات" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;أفضل أدوات فحص الثغرات (Vulnerability Assessment Tools) للشبكات&lt;/h3&gt;&lt;p&gt;أصبحت حماية الشبكات من الهجمات الإلكترونية من أهم التحديات التي تواجه الشركات والمؤسسات وأصحاب البنية التحتية الرقمية. فمع تزايد الاعتماد على الخوادم والخدمات السحابية وأجهزة الشبكات وتطبيقات الويب، أصبحت أي ثغرة أمنية غير مكتشفة قد تمثل نقطة دخول للمهاجمين، وتؤدي إلى تسريب البيانات أو تعطيل الخدمات أو الوصول غير المصرح به إلى الأنظمة.&lt;/p&gt;&lt;p&gt;هنا تأتي أهمية &lt;strong&gt;أدوات فحص الثغرات الأمنية (Vulnerability Assessment Tools)&lt;/strong&gt;، وهي أدوات تساعد مسؤولي الأنظمة وخبراء الأمن السيبراني على اكتشاف نقاط الضعف المعروفة، وتحديد الأنظمة التي تحتاج إلى تحديثات، ومراجعة الإعدادات الأمنية، وترتيب المخاطر حسب درجة خطورتها.&lt;/p&gt;&lt;p&gt;لكن من المهم التمييز بين فحص الثغرات واختبار الاختراق. ففحص الثغرات يركز على اكتشاف نقاط الضعف المحتملة وتقييمها، بينما يتضمن اختبار الاختراق محاولات عملية ومصرحًا بها للتحقق من إمكانية استغلال بعض نقاط الضعف وتأثيرها.&lt;/p&gt;&lt;p&gt;في هذا المقال على موقع &lt;strong&gt;nusurtech.ca&lt;/strong&gt;، سنتعرف على أفضل أدوات فحص الثغرات للشبكات، ومميزات كل أداة، والفرق بينها، وكيف تختار الأداة المناسبة لاحتياجاتك، مع مجموعة من النصائح التي تساعدك على إجراء الفحوص بطريقة آمنة وفعالة.&lt;/p&gt;&lt;h3&gt;ما هو فحص الثغرات الأمنية للشبكات؟&lt;/h3&gt;&lt;p&gt;فحص الثغرات الأمنية هو عملية منهجية تهدف إلى تحديد نقاط الضعف المحتملة في أجهزة الشبكة والخوادم وأنظمة التشغيل والخدمات والتطبيقات المرتبطة بها.&lt;/p&gt;&lt;p&gt;قد تشمل هذه النقاط:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;استخدام إصدارات قديمة من أنظمة التشغيل أو البرامج.&lt;/li&gt;&lt;li&gt;وجود خدمات غير ضرورية مكشوفة على الشبكة.&lt;/li&gt;&lt;li&gt;إعدادات أمنية غير صحيحة.&lt;/li&gt;&lt;li&gt;استخدام بروتوكولات أو خوارزميات تشفير ضعيفة.&lt;/li&gt;&lt;li&gt;وجود ثغرات معروفة في البرمجيات المثبتة.&lt;/li&gt;&lt;li&gt;أخطاء في إعدادات التحكم بالوصول.&lt;/li&gt;&lt;li&gt;إعدادات غير آمنة لأجهزة التوجيه والمحولات والجدران النارية.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;تعمل أدوات الفحص على جمع معلومات عن الأصول المستهدفة، ثم تقارن النتائج بقواعد بيانات الثغرات المعروفة وقواعد الفحص والإعدادات الأمنية. بعد ذلك، تعرض النتائج في تقارير تساعد الفريق التقني على تحديد الأولويات ومعالجة المشكلات.&lt;/p&gt;&lt;p&gt;مع ذلك، ليست كل نتيجة تظهرها أداة الفحص ثغرة مؤكدة؛ فقد تظهر نتائج إيجابية كاذبة (False Positives)، وقد تفشل الأداة في اكتشاف بعض المشكلات. لذلك، يجب مراجعة النتائج والتحقق منها قبل اتخاذ القرارات.&lt;/p&gt;&lt;h3&gt;لماذا تحتاج المؤسسات إلى أدوات فحص الثغرات؟&lt;/h3&gt;&lt;p&gt;تساعد أدوات فحص الثغرات المؤسسات على تحسين وضعها الأمني من خلال اكتشاف المشكلات قبل أن تتحول إلى حوادث فعلية.&lt;/p&gt;&lt;p&gt;ومن أهم فوائدها:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;اكتشاف الثغرات مبكرًا:&lt;/strong&gt; تساعد الفحوص الدورية على تحديد الأنظمة الضعيفة قبل استغلالها، خاصة عند ظهور ثغرات جديدة في البرامج المستخدمة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تقليل المخاطر الأمنية:&lt;/strong&gt; تتيح النتائج ترتيب المشكلات حسب خطورتها وتأثيرها المحتمل على الأنظمة والبيانات.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;دعم إدارة التحديثات:&lt;/strong&gt; تساعد تقارير الفحص على معرفة الأجهزة التي تحتاج إلى تحديثات أمنية أو تغييرات في الإعدادات.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تحسين الامتثال:&lt;/strong&gt; قد تدعم نتائج الفحص بعض متطلبات المعايير والسياسات الأمنية، بحسب نطاق الفحص وطبيعة المؤسسة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;توثيق الوضع الأمني:&lt;/strong&gt; توفر الأدوات تقارير يمكن مقارنتها بمرور الوقت لمعرفة ما إذا كانت المخاطر تتراجع أم تتزايد.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تقليل الاعتماد على الفحص اليدوي:&lt;/strong&gt; تساعد الأتمتة على تغطية عدد كبير من الأنظمة بسرعة أكبر، مع بقاء الحاجة إلى المراجعة البشرية.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لكن استخدام أداة فحص وحده لا يجعل الشبكة آمنة؛ إذ يجب ربط النتائج بخطة معالجة واضحة، وتحديد المسؤوليات، ومتابعة تنفيذ الإصلاحات.&lt;/p&gt;&lt;h3&gt;أفضل أدوات فحص الثغرات الأمنية للشبكات&lt;/h3&gt;&lt;p&gt;توجد أدوات مجانية ومفتوحة المصدر، وأخرى تجارية توفر خصائص متقدمة مثل إدارة الأصول، والتقارير المركزية، والتكامل مع أنظمة إدارة التحديثات. ويعتمد الاختيار على حجم الشبكة، ونوع الأصول، والميزانية، والخبرة الفنية المتاحة.&lt;/p&gt;&lt;h3&gt;1. أداة Nessus&lt;/h3&gt;&lt;p&gt;تُعد أداة &lt;strong&gt;&lt;a href="https://www.nusurtech.ca/2023/06/what-is-nessus-tool.html"&gt;Nessus&lt;/a&gt;&lt;/strong&gt; من الأدوات المعروفة في مجال فحص الثغرات الأمنية، وتُستخدم لفحص الخوادم وأجهزة الشبكات وأنظمة التشغيل والخدمات ضمن نطاقات مصرح بها.&lt;/p&gt;&lt;p&gt;تساعد الأداة على اكتشاف ثغرات معروفة، وتحديد الأنظمة التي تحتاج إلى تحديثات، ومراجعة بعض الإعدادات الأمنية، ثم تقديم تقارير تتضمن معلومات عن النتائج ومستويات خطورتها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;واجهة استخدام مناسبة للعديد من مسؤولي الأنظمة.&lt;/li&gt;&lt;li&gt;قاعدة واسعة من اختبارات الثغرات.&lt;/li&gt;&lt;li&gt;تقارير تساعد على تحديد الأولويات.&lt;/li&gt;&lt;li&gt;دعم فحوص الشبكات والخوادم وفق إمكانات المنتج وإصداره.&lt;/li&gt;&lt;li&gt;إمكانية استخدام نتائج الفحص لتخطيط أعمال الصيانة والتحديث.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لمن تناسب؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تناسب Nessus مسؤولي الشبكات وفرق الأمن التي تحتاج إلى أداة متخصصة في فحص الثغرات. وتختلف الخصائص والتكلفة حسب الإصدار والترخيص، لذا يُنصح بمراجعة الموقع الرسمي قبل الاختيار.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://www.tenable.com/products/nessus"&gt;Tenable Nessus&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;2. OpenVAS وGreenbone&lt;/h3&gt;&lt;p&gt;تُعد OpenVAS، ضمن منظومة Greenbone Vulnerability Management، خيارًا معروفًا لمن يبحث عن حلول لفحص الثغرات مع إمكانات مفتوحة المصدر أو إصدارات تجارية مدارة.&lt;/p&gt;&lt;p&gt;تستطيع المنظومة إجراء فحوص على الأنظمة والخدمات ضمن النطاق المحدد، وتوفير تقارير عن الثغرات المحتملة ومستويات خطورتها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;توفر خيارات مفتوحة المصدر.&lt;/li&gt;&lt;li&gt;إمكانية إدارة الفحوص والمهام من خلال واجهة مخصصة.&lt;/li&gt;&lt;li&gt;تقديم تقارير تساعد على مراجعة نتائج الفحص.&lt;/li&gt;&lt;li&gt;إمكانية استخدامها في المختبرات التعليمية والبيئات المؤسسية بحسب التوزيعة والإصدار.&lt;/li&gt;&lt;li&gt;مرونة أكبر للفرق التي تستطيع إدارة البنية التحتية للأداة وتحديث قواعد الفحص.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ما الذي يجب مراعاته؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;قد يحتاج إعداد الأداة وصيانتها إلى خبرة تقنية، كما أن أداء الفحص وجودة النتائج يعتمدان على الإعدادات ومصادر الاختبارات والإصدار المستخدم.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لمن تناسب؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تناسب فرق الأمن السيبراني والمؤسسات التي ترغب في تجربة حل مرن، ولديها القدرة على إدارة بيئة الفحص وصيانتها.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://www.greenbone.net/"&gt;Greenbone&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;3. Nmap&lt;/h3&gt;&lt;p&gt;تُستخدم أداة &lt;strong&gt;&lt;a href="https://www.nusurtech.ca/2023/06/nmap-and-zenmap-tools.html"&gt;Nmap&lt;/a&gt;&lt;/strong&gt; على نطاق واسع لاكتشاف الأجهزة المتصلة بالشبكات، وتحديد المنافذ المفتوحة، والتعرف على الخدمات والإصدارات التي تعرضها الأنظمة.&lt;/p&gt;&lt;p&gt;من المهم معرفة أن Nmap ليست بديلًا كاملًا عن ماسحات الثغرات المتخصصة؛ فهي أداة لاكتشاف الشبكة والخدمات، ويمكن الاستفادة من بعض إمكاناتها في جمع معلومات أولية تساعد في تحديد الأنظمة التي تحتاج إلى مراجعة أمنية إضافية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;اكتشاف الأجهزة والخدمات ضمن النطاق المصرح به.&lt;/li&gt;&lt;li&gt;التعرف على المنافذ المفتوحة والخدمات المتاحة.&lt;/li&gt;&lt;li&gt;توفير خيارات متنوعة لفحص الشبكات.&lt;/li&gt;&lt;li&gt;دعم نظام NSE الذي يضيف إمكانات للفحص واكتشاف بعض المشكلات.&lt;/li&gt;&lt;li&gt;العمل على أنظمة تشغيل متعددة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لمن تناسب؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تناسب مسؤولي الشبكات والطلاب والمتخصصين الذين يريدون فهم بنية الشبكة ومعرفة الخدمات التي تعرضها الأنظمة.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://nmap.org/"&gt;Nmap&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;4. Qualys VMDR&lt;/h3&gt;&lt;p&gt;توفر Qualys منصة لإدارة الثغرات واكتشاف الأصول وتقييم المخاطر، وتُستخدم في المؤسسات التي تحتاج إلى متابعة عدد كبير من الأجهزة والخوادم عبر بيئات مختلفة.&lt;/p&gt;&lt;p&gt;تساعد المنصة على ربط معلومات الأصول بنتائج الفحص، وتحديد الثغرات ذات الأولوية، ومتابعة أعمال المعالجة وفق الإمكانات المتاحة في الترخيص.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;إدارة مركزية للأصول والثغرات.&lt;/li&gt;&lt;li&gt;إمكانات لتحديد الأولويات بحسب المخاطر.&lt;/li&gt;&lt;li&gt;دعم البيئات المؤسسية الكبيرة.&lt;/li&gt;&lt;li&gt;تقارير تساعد على متابعة حالة المعالجة.&lt;/li&gt;&lt;li&gt;تكاملات مع أدوات وعمليات أمنية أخرى بحسب المنتج والترخيص.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لمن تناسب؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تناسب المؤسسات التي تحتاج إلى إدارة مستمرة للثغرات، خصوصًا عندما تكون الشبكة موزعة بين مكاتب متعددة وخوادم محلية وبيئات سحابية.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://www.qualys.com/"&gt;Qualys&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;5. Rapid7 InsightVM&lt;/h3&gt;&lt;p&gt;تقدم Rapid7 منصة InsightVM لإدارة الثغرات، وتساعد فرق الأمن على اكتشاف الأصول الضعيفة وتقييم المخاطر ومتابعة التقدم في معالجة المشكلات.&lt;/p&gt;&lt;p&gt;لا يقتصر الهدف على إنتاج قائمة طويلة بالثغرات، بل يشمل دعم الفريق في تحديد المشكلات التي تستحق المعالجة أولًا، وفقًا للمعلومات التي توفرها المنصة وإعداداتها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;عرض مركزي لحالة الثغرات.&lt;/li&gt;&lt;li&gt;إمكانات لتحديد أولويات المعالجة.&lt;/li&gt;&lt;li&gt;دعم التقارير ومتابعة التقدم.&lt;/li&gt;&lt;li&gt;تكاملات مع سير العمل الأمني لدى المؤسسات.&lt;/li&gt;&lt;li&gt;إمكانات مناسبة للفرق التي تحتاج إلى متابعة مستمرة بدلًا من الفحص المنفصل فقط.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لمن تناسب؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تناسب المؤسسات التي تمتلك فريقًا أمنيًا وتحتاج إلى إدارة متكررة للثغرات عبر عدد كبير من الأنظمة.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://www.rapid7.com/products/insightvm/"&gt;Rapid7 InsightVM&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;6. Microsoft Defender Vulnerability Management&lt;/h3&gt;&lt;p&gt;توفر Microsoft إمكانات لإدارة الثغرات واكتشاف نقاط الضعف في الأجهزة والبرمجيات ضمن منظومة Defender، مع اختلاف الخصائص حسب الترخيص والمنتجات المستخدمة.&lt;/p&gt;&lt;p&gt;يمكن أن تساعد هذه الإمكانات فرق تقنية المعلومات والأمن على تحديد البرامج القديمة، ومراجعة الثغرات المعروفة، والحصول على توصيات للمعالجة، خصوصًا في البيئات التي تعتمد على أجهزة Windows ومنظومة Microsoft الأمنية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;دمج معلومات الثغرات مع أدوات أمنية أخرى في منظومة Microsoft.&lt;/li&gt;&lt;li&gt;تقديم توصيات لمعالجة بعض المشكلات.&lt;/li&gt;&lt;li&gt;دعم إدارة المخاطر على الأجهزة المشمولة بالخدمة.&lt;/li&gt;&lt;li&gt;إمكانية الاستفادة من المعلومات المتاحة في عمليات المتابعة الأمنية.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لمن تناسب؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تناسب المؤسسات التي تستخدم منتجات Microsoft الأمنية وتريد الاستفادة من التكامل بين إدارة الأجهزة واكتشاف الثغرات.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://learn.microsoft.com/en-us/defender-vulnerability-management/"&gt;Microsoft Defender Vulnerability Management&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;7. Nikto&lt;/h3&gt;&lt;p&gt;&lt;a href="https://www.nusurtech.ca/2026/08/common-tools-used-by-ethical-hackers.html"&gt;Nikto&lt;/a&gt; أداة مفتوحة المصدر تُستخدم لفحص خوادم الويب بحثًا عن مجموعة من المشكلات والتهيئات غير الآمنة والملفات المعروفة التي قد تستحق المراجعة.&lt;/p&gt;&lt;p&gt;ورغم ارتباطها بخوادم الويب أكثر من ارتباطها بأجهزة الشبكات عمومًا، فإنها مفيدة ضمن برنامج تقييم أمني يشمل الخوادم التي تستضيف تطبيقات الويب.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;فحص بعض الإعدادات والمكونات الشائعة في خوادم الويب.&lt;/li&gt;&lt;li&gt;المساعدة في اكتشاف ملفات أو مسارات معروفة تستحق المراجعة.&lt;/li&gt;&lt;li&gt;مناسبة للتعلم والفحوص المصرح بها.&lt;/li&gt;&lt;li&gt;إمكانية استخدامها إلى جانب أدوات أخرى لتكوين صورة أوضح عن وضع الخادم.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ما حدودها؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لا تُعد Nikto أداة شاملة لإدارة الثغرات على مستوى المؤسسة، ولا يغني استخدامها عن مراجعة إعدادات الخادم أو إجراء اختبارات أعمق عند الحاجة.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://cirt.net/Nikto2"&gt;Nikto&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;8. Nuclei&lt;/h3&gt;&lt;p&gt;تُستخدم أداة Nuclei لإجراء فحوص أمنية اعتمادًا على قوالب (Templates) تصف اختبارات محددة لمشكلات أو ثغرات أو إعدادات معروفة.&lt;/p&gt;&lt;p&gt;تتميز بإمكانية توسيع نطاق الفحوص باستخدام القوالب، ويمكن أن تكون مفيدة لفرق الأمن التي تريد أتمتة بعض الاختبارات ضمن نطاقات مصرح بها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;أهم المميزات:&lt;/strong&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;الاعتماد على قوالب قابلة للتحديث والتخصيص.&lt;/li&gt;&lt;li&gt;إمكانية دمج الفحوص في بعض عمليات التطوير والتكامل المستمر.&lt;/li&gt;&lt;li&gt;دعم اختبارات متنوعة بحسب القوالب المستخدمة.&lt;/li&gt;&lt;li&gt;توفير طريقة قابلة للأتمتة لإعادة فحص بعض المشكلات المعروفة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ما الذي يجب مراعاته؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تعتمد النتائج على جودة القوالب وتحديثها، وقد تؤدي القوالب غير المناسبة أو الإعدادات غير الصحيحة إلى طلبات غير مرغوبة أو نتائج مضللة. لذلك، ينبغي مراجعة القوالب وفهم تأثيرها قبل استخدامها على الأنظمة الحقيقية.&lt;/p&gt;&lt;p&gt;الموقع الرسمي: &lt;a href="https://github.com/projectdiscovery/nuclei"&gt;Nuclei&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;مقارنة مختصرة بين أدوات فحص الثغرات&lt;/h3&gt;&lt;p&gt;يساعد الجدول التالي على اختيار نقطة البداية المناسبة، لكنه لا يمثل ترتيبًا مطلقًا للأفضل؛ فالأداة الأنسب تعتمد على طبيعة الشبكة ومتطلبات العمل.&lt;/p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;th&gt;الأداة&lt;/th&gt;&lt;th&gt;الاستخدام الأساسي&lt;/th&gt;&lt;th&gt;أبرز ما يميزها&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nessus&lt;/td&gt;&lt;td&gt;فحص الثغرات&lt;/td&gt;&lt;td&gt;واجهة متخصصة وتقارير مفصلة&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;OpenVAS / Greenbone&lt;/td&gt;&lt;td&gt;إدارة وفحص الثغرات&lt;/td&gt;&lt;td&gt;خيارات مفتوحة المصدر ومرونة في الإدارة&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nmap&lt;/td&gt;&lt;td&gt;اكتشاف الشبكة والخدمات&lt;/td&gt;&lt;td&gt;معرفة الأجهزة والمنافذ والخدمات&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Qualys VMDR&lt;/td&gt;&lt;td&gt;إدارة الثغرات على نطاق مؤسسي&lt;/td&gt;&lt;td&gt;إدارة مركزية للأصول والمخاطر&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Rapid7 InsightVM&lt;/td&gt;&lt;td&gt;إدارة الثغرات والمعالجة&lt;/td&gt;&lt;td&gt;متابعة الأولويات والتقدم&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Microsoft Defender VM&lt;/td&gt;&lt;td&gt;إدارة الثغرات في البيئات المدعومة&lt;/td&gt;&lt;td&gt;التكامل مع منظومة Microsoft&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nikto&lt;/td&gt;&lt;td&gt;فحص خوادم الويب&lt;/td&gt;&lt;td&gt;مراجعة بعض الإعدادات والمشكلات المعروفة&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Nuclei&lt;/td&gt;&lt;td&gt;فحوص تعتمد على القوالب&lt;/td&gt;&lt;td&gt;الأتمتة وإمكانية التخصيص&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;h3&gt;كيف تختار أداة فحص الثغرات المناسبة؟&lt;/h3&gt;&lt;p&gt;لا ينبغي اختيار الأداة بناءً على شهرتها فقط. من الأفضل تحديد الاحتياجات الفعلية للشبكة ومقارنتها بالخصائص التي تقدمها كل أداة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. حجم الشبكة وعدد الأجهزة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;قد تكون أداة بسيطة مناسبة لمختبر تعليمي أو شبكة صغيرة، بينما تحتاج مؤسسة كبيرة إلى منصة تدير الأصول وتنفذ الفحوص الدورية وتتابع المعالجة مركزيًا.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. نوع الأنظمة التي تريد فحصها&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تأكد من أن الأداة تدعم أنظمة التشغيل وأجهزة الشبكات والخدمات المستخدمة لديك. فبعض الأدوات متخصصة في اكتشاف الخدمات، بينما تركز أخرى على الثغرات أو إدارة المخاطر.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. التكلفة والترخيص&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;قارن بين تكلفة الترخيص، وتكاليف التشغيل والصيانة، ومتطلبات الأجهزة، والوقت الذي يحتاج إليه الفريق لإدارة الأداة. وقد يكون الحل مفتوح المصدر مناسبًا عندما تتوفر الخبرة اللازمة لإدارته.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. دقة النتائج&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ابحث عن الأدوات التي توفر معلومات كافية للتحقق من النتائج، وتساعدك على تقليل النتائج الإيجابية الكاذبة. لا تعتمد على درجة الخطورة وحدها دون النظر إلى أهمية الأصل المتأثر وسياق المؤسسة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5. التقارير والتكامل&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كنت تعمل ضمن فريق، فقد تحتاج إلى تقارير قابلة للتصدير وتكامل مع أنظمة إدارة التذاكر أو إدارة الأصول أو أدوات المراقبة الأمنية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6. سهولة الاستخدام والصيانة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;الأداة الجيدة ليست بالضرورة الأكثر تعقيدًا؛ بل هي الأداة التي يستطيع الفريق استخدامها وتحديثها ومراجعة نتائجها باستمرار.&lt;/p&gt;&lt;h3&gt;ما الفرق بين Vulnerability Assessment وPenetration Testing؟&lt;/h3&gt;&lt;p&gt;من المفاهيم المهمة في الأمن السيبراني معرفة الفرق بين تقييم الثغرات واختبار الاختراق.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تقييم الثغرات (Vulnerability Assessment):&lt;/strong&gt; يركز على اكتشاف نقاط الضعف المحتملة وتقييمها وترتيبها بحسب الأولوية، وغالبًا ما يعتمد على أدوات الفحص الآلي مع مراجعة النتائج.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;اختبار الاختراق (Penetration Testing):&lt;/strong&gt; يتضمن اختبارات عملية ومصرحًا بها للتحقق من إمكانية استغلال نقاط ضعف محددة، وفهم أثرها الفعلي ضمن النطاق المتفق عليه.&lt;/p&gt;&lt;p&gt;يمكن أن يكمل النوعان أحدهما الآخر. فالفحص الدوري يساعد على اكتشاف مشكلات كثيرة على نطاق واسع، بينما يمكن لاختبار الاختراق أن يوفر فهمًا أعمق لتأثير بعض المشكلات في سيناريوهات محددة.&lt;/p&gt;&lt;p&gt;ولا يعني اجتياز فحص الثغرات أن النظام خالٍ من المخاطر؛ إذ قد توجد ثغرات منطقية أو أخطاء في تصميم الصلاحيات لا تستطيع الأدوات الآلية اكتشافها بسهولة.&lt;/p&gt;&lt;h3&gt;أفضل الممارسات عند إجراء فحص الثغرات&lt;/h3&gt;&lt;p&gt;للحصول على نتائج مفيدة وتقليل التأثير في الشبكة، اتبع مجموعة من الممارسات الأساسية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;احصل على تصريح واضح:&lt;/strong&gt; افحص فقط الأنظمة التي تملكها أو لديك إذن صريح لاختبارها.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;حدد نطاق الفحص:&lt;/strong&gt; وثّق عناوين IP والأجهزة والخدمات المسموح بفحصها، واستبعد الأنظمة غير المشمولة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;ابدأ بجرد الأصول:&lt;/strong&gt; تأكد من معرفة الأجهزة والخدمات الموجودة قبل محاولة تقييم مخاطرها.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;اختر إعدادات مناسبة:&lt;/strong&gt; بعض الفحوص قد تؤثر في أداء الأجهزة القديمة أو الخدمات الحساسة، لذا ابدأ بإعدادات متحفظة عند الحاجة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;حدّث قواعد الفحص:&lt;/strong&gt; قد تفوتك ثغرات جديدة إذا كانت قواعد الأداة قديمة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;راجع النتائج يدويًا:&lt;/strong&gt; تحقق من النتائج المهمة، ولا تفترض أن كل تنبيه يمثل ثغرة قابلة للاستغلال.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;رتّب الأولويات بحسب المخاطر:&lt;/strong&gt; ضع في الحسبان شدة الثغرة، وإمكانية استغلالها، وأهمية النظام المتأثر، ومدى تعرضه للإنترنت.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;عالج المشكلات وأعد الفحص:&lt;/strong&gt; تأكد من أن التحديث أو التغيير الأمني نجح فعلًا في إزالة المشكلة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;احتفظ بالتقارير بأمان:&lt;/strong&gt; قد تحتوي نتائج الفحص على معلومات حساسة عن الشبكة، لذلك يجب تقييد الوصول إليها.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;أخطاء شائعة يجب تجنبها&lt;/h3&gt;&lt;p&gt;قد تقل فائدة أدوات الفحص إذا استخدمت بطريقة غير منظمة. ومن أبرز الأخطاء الشائعة:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;إجراء الفحص مرة واحدة فقط وعدم تكراره.&lt;/li&gt;&lt;li&gt;تجاهل الثغرات ذات الأولوية العالية بسبب كثرة النتائج.&lt;/li&gt;&lt;li&gt;الاعتماد على أداة واحدة لجميع أنواع الأصول.&lt;/li&gt;&lt;li&gt;تحديث الأنظمة دون اختبار التغييرات في الخدمات الحساسة.&lt;/li&gt;&lt;li&gt;تجاهل النتائج الإيجابية الكاذبة دون التحقق منها.&lt;/li&gt;&lt;li&gt;مشاركة تقارير الفحص علنًا، رغم احتوائها على تفاصيل داخلية.&lt;/li&gt;&lt;li&gt;إجراء فحوص على شبكات لا تملك تصريحًا باختبارها.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;تجنب هذه الأخطاء من خلال وضع سياسة واضحة للفحص، وتحديد المسؤوليات، وربط نتائج الفحص بعملية إدارة التحديثات والاستجابة للحوادث.&lt;/p&gt;&lt;p&gt;تُعد أدوات فحص الثغرات الأمنية من العناصر المهمة في أي برنامج لحماية الشبكات. وتوفر أدوات مثل Nessus وOpenVAS وNmap وQualys وRapid7 وMicrosoft Defender وNikto وNuclei إمكانات مختلفة تساعد على اكتشاف نقاط الضعف وفهم الخدمات المكشوفة ومتابعة معالجة المخاطر.&lt;/p&gt;&lt;p&gt;لا توجد أداة واحدة هي الأفضل لجميع المؤسسات. فإذا كنت مبتدئًا، فقد يكون من المفيد البدء بتعلم اكتشاف الشبكات باستخدام Nmap، ثم تجربة إحدى أدوات فحص الثغرات المتخصصة ضمن مختبر آمن. أما المؤسسات الكبيرة، فقد تحتاج إلى منصة لإدارة الأصول والثغرات وتنسيق أعمال المعالجة على نطاق واسع.&lt;/p&gt;&lt;p&gt;الأهم من اختيار الأداة هو استخدام نتائجها بطريقة صحيحة: اكتشف الأصول، وافحصها بانتظام، وتحقق من النتائج، ورتّب الأولويات، وعالج المشكلات، ثم أعد الفحص للتأكد من نجاح المعالجة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تنبيه أمني:&lt;/strong&gt; استخدم أدوات فحص الثغرات على الشبكات والأجهزة التي تملكها أو لديك تصريح واضح بفحصها فقط. قد تؤثر بعض أنواع الفحص في أداء الأنظمة أو الخدمات، لذا يجب تحديد النطاق واختيار الإعدادات المناسبة قبل التنفيذ.&lt;/p&gt;&lt;h3&gt;المصادر الرسمية&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.tenable.com/products/nessus"&gt;Tenable Nessus&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.greenbone.net/"&gt;Greenbone&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://nmap.org/"&gt;Nmap&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.qualys.com/"&gt;Qualys&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://www.rapid7.com/products/insightvm/"&gt;Rapid7 InsightVM&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://learn.microsoft.com/en-us/defender-vulnerability-management/"&gt;Microsoft Defender Vulnerability Management&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://cirt.net/Nikto2"&gt;Nikto&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/projectdiscovery/nuclei"&gt;ProjectDiscovery Nuclei&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content><link href="https://www.nusurtech.ca/feeds/5462493043378551107/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/best-network-vulnerability-assessment-tools.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5462493043378551107" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5462493043378551107" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/best-network-vulnerability-assessment-tools.html" rel="alternate" title="أفضل أدوات فحص الثغرات للشبكات" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKyXL8B7Kvfzuc_RZLEpv85sy-8_wz10_5ZGjjJEgoYLfIXnB-OE3CZ8sSyzrNWhiTvxJz2y7L5vT7dgTQZOkiFnhnzHhKa5SehJzAiHxc9fZVkk3Oyj2UqOkiuAIN0e5mlrf4nX-u_nsjn_XzJudoTLx4PrfNmLFi3z72dXcSwn2mP2bhyphenhyphen6T2sxZRMRhK/s72-c/imageedit_1_4171208420.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-7280728781523529852</id><published>2026-10-22T09:13:02.684+03:00</published><updated>2026-10-22T09:13:02.685+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="توعية"/><title type="text">أهم الممارسات الأمنية Security Best Practices لحماية تطبيقات Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAjcLvik__plAv0JytbgEbjG3Kqmb3wGu6h0VPrQvPGgKNEskN5iDEKG7OlMqJSNYs6IPlw8ls50drJDxqlY4iowx_lfjsSH1PSqhdts00YaKVir7GC_E0fspEhALtzfM9LYKU8FSs6XY5i05TozsNMMyuwSHdnPf_dF4s6meIlPOVM47JMuh567ZoGnOD/s640/imageedit_1_2890659900.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="أهم الممارسات الأمنية (Security Best Practices) لحماية تطبيقات Laravel من الاختراق" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAjcLvik__plAv0JytbgEbjG3Kqmb3wGu6h0VPrQvPGgKNEskN5iDEKG7OlMqJSNYs6IPlw8ls50drJDxqlY4iowx_lfjsSH1PSqhdts00YaKVir7GC_E0fspEhALtzfM9LYKU8FSs6XY5i05TozsNMMyuwSHdnPf_dF4s6meIlPOVM47JMuh567ZoGnOD/s1600/imageedit_1_2890659900.webp" title="أهم الممارسات الأمنية (Security Best Practices) لحماية تطبيقات Laravel من الاختراق" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;أهم الممارسات الأمنية لحماية تطبيقات Laravel من الاختراق&lt;/h3&gt;&lt;p&gt;يُعد إطار العمل &lt;strong&gt;&lt;a href="https://www.nusurtech.ca/2026/09/what-is-laravel.html" target="_blank"&gt;Laravel&lt;/a&gt;&lt;/strong&gt; من أشهر أطر تطوير تطبيقات الويب باستخدام لغة PHP، وذلك بفضل سهولة استخدامه، وتنظيم بنيته البرمجية، وتوفيره مجموعة من الأدوات المدمجة التي تساعد المطورين على بناء تطبيقات آمنة وقابلة للتوسع. ومع ذلك، فإن استخدام إطار عمل قوي لا يعني أن التطبيق محمي تلقائيًا من جميع الهجمات الإلكترونية.&lt;/p&gt;&lt;p&gt;قد تنتج الثغرات الأمنية عن أخطاء برمجية بسيطة، أو إعدادات خادم غير صحيحة، أو استخدام مكتبات قديمة، أو منح المستخدمين صلاحيات أكبر من اللازم. وقد تؤدي هذه المشكلات إلى تسريب البيانات، أو الاستيلاء على الحسابات، أو التلاعب بقاعدة البيانات، أو حتى السيطرة على أجزاء من الخادم.&lt;/p&gt;&lt;p&gt;لذلك، فإن تطبيق &lt;strong&gt;Security Best Practices في Laravel&lt;/strong&gt; ليس خطوة اختيارية، بل جزء أساسي من دورة تطوير التطبيقات ونشرها وصيانتها.&lt;/p&gt;&lt;p&gt;في هذا الدليل على موقع &lt;strong&gt;nusurtech.ca&lt;/strong&gt;، سنتعرف على أهم الممارسات الأمنية التي ينبغي لكل مطور Laravel اتباعها، مع أمثلة عملية وأوامر برمجية تساعدك على تقليل المخاطر وتحسين مستوى حماية تطبيقك.&lt;/p&gt;&lt;h3&gt;1. تعطيل وضع التصحيح Debug Mode في بيئة الإنتاج&lt;/h3&gt;&lt;p&gt;من أهم خطوات تأمين تطبيق Laravel التأكد من تعطيل وضع التصحيح عند تشغيل التطبيق في بيئة الإنتاج (Production).&lt;/p&gt;&lt;p&gt;أثناء التطوير، يساعد الخيار &lt;code&gt;APP_DEBUG&lt;/code&gt; المطور على معرفة تفاصيل الأخطاء البرمجية، لكنه قد يكشف معلومات حساسة عند تفعيله على موقع متاح للجمهور، مثل تفاصيل الاستثناءات، ومسارات الملفات، ومعلومات الاتصال، وأحيانًا أجزاء من بيانات الطلب.&lt;/p&gt;&lt;p&gt;افتح ملف &lt;code&gt;.env&lt;/code&gt; واضبط الإعدادات التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;APP_ENV=production
APP_DEBUG=false
&lt;/pre&gt;
&lt;p&gt;بعد تعديل الإعدادات، تأكد من أن إعدادات الإنتاج الفعلية تعكس هذه القيم، خصوصًا إذا كان التطبيق يستخدم إعدادات مخزنة مؤقتًا (Configuration Cache) أو متغيرات بيئة يوفرها نظام الاستضافة.&lt;/p&gt;&lt;p&gt;يمكنك إعادة بناء إعدادات Laravel المخزنة مؤقتًا باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan config:cache
&lt;/pre&gt;
&lt;p&gt;لا تستخدم هذا الأمر قبل التأكد من صحة إعدادات البيئة المستخدمة في النشر. كما ينبغي تسجيل الأخطاء داخليًا دون عرض تفاصيلها للمستخدم النهائي.&lt;/p&gt;&lt;p&gt;يمكنك مراجعة دليل الأمان الخاص بمشروع OWASP لمعرفة المزيد عن إعدادات Laravel الآمنة. &amp;lt;Cite refs={["turn822785search0"]}/&amp;gt;&lt;/p&gt;&lt;h3&gt;2. حماية ملف .env والأسرار الحساسة&lt;/h3&gt;&lt;p&gt;يحتوي ملف &lt;code&gt;.env&lt;/code&gt; عادةً على معلومات بالغة الأهمية، مثل بيانات الاتصال بقاعدة البيانات، ومفتاح التطبيق، وبيانات خدمات البريد الإلكتروني، ومفاتيح واجهات API.&lt;/p&gt;&lt;p&gt;إذا تمكن المهاجم من الوصول إلى هذا الملف، فقد يستطيع استخدام بيانات الاعتماد المسربة للوصول إلى خدمات التطبيق أو تعديل بياناته.&lt;/p&gt;&lt;p&gt;لحماية هذه المعلومات، اتبع الممارسات التالية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;لا ترفع ملف &lt;code&gt;.env&lt;/code&gt; إلى مستودع Git العام أو الخاص دون ضوابط مناسبة.&lt;/li&gt;&lt;li&gt;تأكد من وجود &lt;code&gt;.env&lt;/code&gt; داخل ملف &lt;code&gt;.gitignore&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;لا تضع ملفات الأسرار داخل مجلد &lt;code&gt;public&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;اضبط صلاحيات الملفات والمجلدات بحيث لا يستطيع المستخدمون غير المصرح لهم قراءتها.&lt;/li&gt;&lt;li&gt;استخدم مدير أسرار (Secrets Manager) أو آلية آمنة لتوفير الأسرار في بيئات الإنتاج عند توفرها.&lt;/li&gt;&lt;li&gt;غيّر بيانات الاعتماد فورًا إذا اشتبهت في تسريبها.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;مثال على محتوى ينبغي عدم مشاركته علنًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;APP_KEY=your-secret-application-key
DB_PASSWORD=your-database-password
MAIL_PASSWORD=your-mail-password
&lt;/pre&gt;
&lt;p&gt;هذه القيم توضيحية وليست بيانات حقيقية.&lt;/p&gt;&lt;p&gt;وجود ملف &lt;code&gt;.gitignore&lt;/code&gt; لا يكفي وحده؛ فقد يكون الملف قد رُفع إلى المستودع سابقًا، أو جرى تضمينه في سجل Git. لذلك، افحص المستودعات وسجلات النشر، وتعامل مع أي سر مكشوف على أنه مخترق حتى يتم التحقق من العكس.&lt;/p&gt;&lt;p&gt;كذلك، لا تنشر ملف &lt;code&gt;.env&lt;/code&gt; أو بيانات الاتصال بقاعدة البيانات داخل لقطات الشاشة أو سجلات الأخطاء أو ملفات النسخ الاحتياطي المتاحة للعامة.&lt;/p&gt;&lt;p&gt;للتوسع في هذا الموضوع، راجع إرشادات OWASP لإدارة الأسرار. &amp;lt;Cite refs={["turn822785search6"]}/&amp;gt;&lt;/p&gt;&lt;h3&gt;3. استخدام HTTPS وتفعيل إعدادات الاتصال الآمن&lt;/h3&gt;&lt;p&gt;يجب أن يستخدم تطبيق Laravel بروتوكول HTTPS لحماية البيانات أثناء انتقالها بين المتصفح والخادم.&lt;/p&gt;&lt;p&gt;يساعد HTTPS على تشفير الاتصال، مما يقلل فرص اعتراض كلمات المرور وملفات تعريف الارتباط والبيانات الحساسة عبر الشبكات غير الآمنة.&lt;/p&gt;&lt;p&gt;لتحسين الحماية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;ثبّت شهادة TLS صالحة من جهة موثوقة.&lt;/li&gt;&lt;li&gt;أعد توجيه طلبات HTTP إلى HTTPS من خلال إعدادات الخادم أو الوكيل العكسي (Reverse Proxy).&lt;/li&gt;&lt;li&gt;تأكد من أن Laravel يتعرف بشكل صحيح على البروتوكول الأصلي عند استخدام موازن تحميل أو Proxy.&lt;/li&gt;&lt;li&gt;فعّل خاصية &lt;code&gt;Secure&lt;/code&gt; لملفات تعريف الارتباط في بيئة الإنتاج التي تستخدم HTTPS فقط.&lt;/li&gt;&lt;li&gt;استخدم إعداد &lt;code&gt;HttpOnly&lt;/code&gt; لمنع JavaScript من قراءة ملفات تعريف الارتباط الخاصة بالجلسة.&lt;/li&gt;&lt;li&gt;اضبط خاصية &lt;code&gt;SameSite&lt;/code&gt; بما يتناسب مع طريقة عمل التطبيق.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكن أن تكون إعدادات الجلسة في &lt;code&gt;config/session.php&lt;/code&gt; على النحو التالي، بحسب إصدار Laravel وطريقة النشر:&lt;/p&gt;.
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'http_only' =&amp;gt; true,
'secure' =&amp;gt; true,
'same_site' =&amp;gt; 'lax',
&lt;/pre&gt;
&lt;p&gt;تأكد من أن الإعدادات مناسبة لبيئتك، خاصةً إذا كان التطبيق يعمل خلف Proxy أو يعتمد على نطاقات فرعية أو تكاملات خارجية.&lt;/p&gt;&lt;p&gt;ويمكن أيضًا استخدام ترويسة HTTP المعروفة باسم &lt;code&gt;Strict-Transport-Security&lt;/code&gt; (HSTS) لإخبار المتصفحات باستخدام HTTPS مستقبلًا. لكن يجب تفعيلها بعد التأكد من أن النطاق وجميع الخدمات الفرعية المعنية تعمل عبر HTTPS بصورة صحيحة.&lt;/p&gt;&lt;h3&gt;4. حماية التطبيق من هجمات SQL Injection&lt;/h3&gt;&lt;p&gt;تحدث هجمات SQL Injection عندما يستطيع المهاجم التأثير في استعلام قاعدة البيانات من خلال إدخال بيانات غير موثوقة في استعلام SQL بطريقة غير آمنة.&lt;/p&gt;&lt;p&gt;يوفر Laravel أدوات تساعد على تقليل هذه المخاطر، مثل Eloquent ORM وQuery Builder، اللذين يستخدمان ربط المعاملات (Parameter Binding) في الاستعلامات المعتادة.&lt;/p&gt;&lt;p&gt;على سبيل المثال، تجنب بناء استعلام SQL عن طريق دمج إدخال المستخدم مباشرةً:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;// مثال غير آمن
$email = $request-&amp;gt;input('email');

$users = DB::select(
    "SELECT * FROM users WHERE email = '$email'"
);
&lt;/pre&gt;
&lt;p&gt;بدلًا من ذلك، استخدم الاستعلامات المجهزة أو أدوات Laravel:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$email = $request-&amp;gt;input('email');

$users = DB::table('users')
    -&amp;gt;where('email', $email)
    -&amp;gt;get();
&lt;/pre&gt;
&lt;p&gt;أو استخدم Eloquent:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::where('email', $request-&amp;gt;input('email'))
    -&amp;gt;first();
&lt;/pre&gt;
&lt;p&gt;لكن يجب الانتباه إلى أن استخدام Eloquent لا يجعل كل استعلام آمنًا تلقائيًا. فقد تظهر الثغرات عند دمج إدخال المستخدم مباشرةً في استعلامات خام، أو في أجزاء من الاستعلام لا تدعم ربط المعاملات، مثل بعض أسماء الأعمدة واتجاهات الفرز.&lt;/p&gt;&lt;p&gt;إذا كنت تسمح للمستخدم باختيار ترتيب النتائج، فحدد الخيارات المسموح بها مسبقًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$allowedSortColumns = ['name', 'created_at'];

$sort = $request-&amp;gt;input('sort', 'created_at');

if (! in_array($sort, $allowedSortColumns, true)) {
    $sort = 'created_at';
}

$users = User::orderBy($sort, 'desc')-&amp;gt;get();
&lt;/pre&gt;
&lt;p&gt;الفكرة الأساسية هي عدم التعامل مع إدخال المستخدم باعتباره جزءًا موثوقًا من الاستعلام، حتى لو كان الإدخال قادمًا من واجهة التطبيق نفسها.&lt;/p&gt;&lt;h3&gt;5. التحقق من المدخلات باستخدام Validation&lt;/h3&gt;&lt;p&gt;يجب التحقق من جميع البيانات التي يستقبلها التطبيق من المستخدمين أو من الأنظمة الخارجية، سواء جاءت عبر النماذج أو واجهات API أو معاملات URL.&lt;/p&gt;&lt;p&gt;يساعد التحقق من المدخلات على رفض البيانات غير المتوقعة وتقليل فرص الأخطاء البرمجية وإساءة استخدام الوظائف.&lt;/p&gt;&lt;p&gt;على سبيل المثال، عند إنشاء مستخدم جديد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Models\User;

public function store(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'name' =&amp;gt; ['required', 'string', 'max:100'],
        'email' =&amp;gt; ['required', 'email', 'max:255', 'unique:users,email'],
        'password' =&amp;gt; ['required', 'string', 'min:12'],
    ]);

    $validated['password'] = Hash::make(
        $validated['password']
    );

    User::create($validated);

    return redirect()
        -&amp;gt;back()
        -&amp;gt;with('success', 'تم إنشاء الحساب بنجاح');
}
&lt;/pre&gt;
&lt;p&gt;هذا المثال توضيحي، ويجب مواءمة قواعد التحقق وسياسة كلمات المرور مع احتياجات التطبيق. كما يجب التأكد من أن نموذج &lt;code&gt;User&lt;/code&gt; لا يسمح بتعبئة حقول حساسة بصورة غير مقصودة.&lt;/p&gt;&lt;p&gt;تذكر أن التحقق من المدخلات يجب أن يكون على الخادم، حتى لو كنت تستخدم JavaScript للتحقق من صحة البيانات في المتصفح. فالتحقق في المتصفح يحسن تجربة المستخدم، لكنه لا يشكل حاجزًا أمنيًا موثوقًا.&lt;/p&gt;&lt;h3&gt;6. منع Mass Assignment وتحديد الحقول القابلة للتعديل&lt;/h3&gt;&lt;p&gt;تظهر ثغرة Mass Assignment عندما يسمح التطبيق بتمرير مجموعة من الحقول إلى النموذج دون تحديد دقيق لما يمكن للمستخدم تغييره.&lt;/p&gt;&lt;p&gt;على سبيل المثال، قد يحتوي جدول المستخدمين على حقل &lt;code&gt;is_admin&lt;/code&gt; لتحديد صلاحيات المدير. إذا استطاع المستخدم إرسال هذا الحقل ضمن طلب تحديث الملف الشخصي، فقد يحاول ترقية حسابه إلى مدير.&lt;/p&gt;&lt;p&gt;يمكن استخدام خاصية &lt;code&gt;$fillable&lt;/code&gt; في النموذج لتحديد الحقول المسموح بتعبئتها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;class User extends Authenticatable
{
    protected $fillable = [
        'name',
        'email',
        'password',
    ];
}
&lt;/pre&gt;
&lt;p&gt;لا تضف الحقول الحساسة مثل &lt;code&gt;is_admin&lt;/code&gt; أو &lt;code&gt;role&lt;/code&gt; أو &lt;code&gt;balance&lt;/code&gt; إلى قائمة الحقول القابلة للتعبئة العامة إلا إذا كان ذلك مبررًا ومقيدًا بتصميم آمن.&lt;/p&gt;&lt;p&gt;وعند تحديث البيانات، استخدم البيانات التي اجتازت التحقق فقط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'name' =&amp;gt; ['required', 'string', 'max:100'],
    'email' =&amp;gt; ['required', 'email', 'max:255'],
]);

$user-&amp;gt;update($validated);
&lt;/pre&gt;
&lt;p&gt;ولا تعتمد على إخفاء الحقول في واجهة المستخدم؛ إذ يستطيع المهاجم إرسال طلب HTTP معدل مباشرةً.&lt;/p&gt;&lt;h3&gt;7. تطبيق نظام صلاحيات Authorization بصورة صحيحة&lt;/h3&gt;&lt;p&gt;نجاح المستخدم في تسجيل الدخول لا يعني أنه يملك الحق في الوصول إلى كل البيانات والوظائف.&lt;/p&gt;&lt;p&gt;يجب التمييز بين Authentication، أي التحقق من هوية المستخدم، وAuthorization، أي التحقق من الصلاحيات التي يمتلكها.&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا كان التطبيق يتيح للمستخدمين عرض الطلبات وتعديلها، فيجب التأكد من أن كل مستخدم لا يستطيع الوصول إلى طلبات مستخدم آخر بمجرد تغيير رقم الطلب في عنوان URL.&lt;/p&gt;&lt;p&gt;يمكنك استخدام Policies في Laravel للتحقق من الصلاحيات.&lt;/p&gt;&lt;p&gt;مثال مبسط داخل &lt;code&gt;OrderPolicy&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(User $user, Order $order): bool
{
    return $user-&amp;gt;id === $order-&amp;gt;user_id;
}
&lt;/pre&gt;
&lt;p&gt;ثم داخل Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(Request $request, Order $order)
{
    $this-&amp;gt;authorize('update', $order);

    // التحقق من المدخلات وتحديث الطلب
}
&lt;/pre&gt;
&lt;p&gt;يجب ضبط سياسة الوصول بحسب متطلبات التطبيق الفعلية، بما في ذلك صلاحيات المديرين والمشرفين وأصحاب الموارد.&lt;/p&gt;&lt;p&gt;لا تعتمد على إخفاء الأزرار أو الروابط في الواجهة الأمامية؛ فكل عملية حساسة تحتاج إلى فحص صلاحيات على الخادم.&lt;/p&gt;&lt;p&gt;وتساعدك Policies وGates في تنظيم قواعد التفويض وتطبيقها بصورة واضحة. &amp;lt;Cite refs={["turn822785search0"]}/&amp;gt;&lt;/p&gt;&lt;h3&gt;8. الحماية من هجمات CSRF&lt;/h3&gt;&lt;p&gt;تعني هجمات Cross-Site Request Forgery (CSRF) خداع متصفح المستخدم المسجل دخوله لإرسال طلب غير مرغوب فيه إلى تطبيق يثق به المستخدم.&lt;/p&gt;&lt;p&gt;على سبيل المثال، قد يحاول موقع ضار إرسال طلب لتغيير بيانات الحساب إذا لم يكن التطبيق يتحقق من أن الطلب صدر ضمن السياق الموثوق.&lt;/p&gt;&lt;p&gt;يتضمن Laravel آليات حماية من CSRF ضمن مجموعة Middleware الخاصة بتطبيقات الويب. عند استخدام نماذج Blade، أضف التوجيه &lt;code&gt;@csrf&lt;/code&gt; إلى النماذج التي تنفذ عمليات تغيير البيانات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST" action="{{ route('profile.update') }}"&amp;gt;
    @csrf

    &amp;lt;input
        type="text"
        name="name"
        value="{{ old('name', auth()-&amp;gt;user()-&amp;gt;name) }}"
    &amp;gt;

    &amp;lt;button type="submit"&amp;gt;حفظ التغييرات&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;p&gt;لا تستثنِ المسارات من حماية CSRF لمجرد التخلص من أخطاء الطلبات. إذا كنت تتعامل مع Webhooks خارجية، فصمم آلية تحقق مناسبة، مثل التحقق من التوقيع الرقمي الذي يوفره مزود الخدمة.&lt;/p&gt;&lt;p&gt;أما تطبيقات SPA التي تستخدم Laravel Sanctum، فيجب إعداد المصادقة والكوكيز ورموز CSRF وفقًا لوثائق Sanctum، مع الانتباه إلى إعدادات النطاقات وطلبات الاعتماد المتبادل.&lt;/p&gt;&lt;p&gt;توضح وثائق Laravel الرسمية آلية الحماية من CSRF وكيفية استخدامها في النماذج وتطبيقات SPA. &amp;lt;Cite refs={["turn822785search1","turn822785search3"]}/&amp;gt;&lt;/p&gt;&lt;h3&gt;9. تأمين تسجيل الدخول وكلمات المرور&lt;/h3&gt;&lt;p&gt;تعد صفحات تسجيل الدخول من أكثر الأجزاء التي تستهدفها محاولات الاختراق، خصوصًا هجمات تخمين كلمات المرور (Brute Force) وتجربة كلمات مرور مسربة من خدمات أخرى (Credential Stuffing).&lt;/p&gt;&lt;p&gt;لحماية نظام المصادقة:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;استخدم آليات تخزين كلمات المرور المدمجة في Laravel، مثل &lt;code&gt;Hash::make()&lt;/code&gt;، ولا تخزن كلمات المرور كنص صريح.&lt;/li&gt;&lt;li&gt;فعّل تحديد معدل الطلبات (Rate Limiting) على محاولات تسجيل الدخول.&lt;/li&gt;&lt;li&gt;استخدم المصادقة متعددة العوامل (MFA) للحسابات الحساسة متى أمكن.&lt;/li&gt;&lt;li&gt;أعد إنشاء Session ID بعد تسجيل الدخول لتقليل مخاطر Session Fixation.&lt;/li&gt;&lt;li&gt;وفر آلية آمنة لإعادة تعيين كلمات المرور.&lt;/li&gt;&lt;li&gt;لا تكشف في رسائل الخطأ ما إذا كان البريد الإلكتروني مسجلًا أم لا، إذا كان ذلك قد يساعد على تعداد الحسابات.&lt;/li&gt;&lt;li&gt;وفر وسيلة لإبطال الجلسات عند تسجيل الخروج أو تغيير كلمة المرور وفقًا لتصميم التطبيق.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكن أن يساعد Middleware الخاص بتحديد معدل الطلبات في تقليل محاولات تسجيل الدخول المتكررة. ويجب تصميم حدود الطلبات بما يوازن بين الأمان وتجربة المستخدم، مع مراعاة أن الهجمات قد تأتي من عناوين IP متعددة.&lt;/p&gt;&lt;h3&gt;10. حماية رفع الملفات من الاستغلال&lt;/h3&gt;&lt;p&gt;قد تتحول ميزة رفع الصور أو المستندات إلى نقطة دخول خطيرة إذا سمح التطبيق برفع ملفات تنفيذية أو ملفات ضخمة أو محتويات خبيثة.&lt;/p&gt;&lt;p&gt;لا تعتمد على اسم الملف أو امتداده فقط. استخدم قواعد التحقق المناسبة، وحدد أنواع الملفات والأحجام المسموح بها، وغيّر أسماء الملفات عند تخزينها.&lt;/p&gt;&lt;p&gt;مثال على التحقق من صورة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'avatar' =&amp;gt; [
        'required',
        'image',
        'mimes:jpg,jpeg,png,webp',
        'max:2048',
    ],
]);

$path = $request-&amp;gt;file('avatar')
    -&amp;gt;store('avatars', 'public');
&lt;/pre&gt;
&lt;p&gt;في هذا المثال، الحد الأقصى لحجم الملف هو 2048 كيلوبايت وفقًا لقواعد التحقق المستخدمة.&lt;/p&gt;&lt;p&gt;بالنسبة إلى الملفات الخاصة، يفضل تخزينها على قرص غير عام، ثم توفيرها للمستخدم بعد التحقق من هويته وصلاحياته. أما الملفات التي يجب إتاحتها للجمهور، فاحرص على ألا يستطيع الخادم تنفيذ محتوياتها كبرامج.&lt;/p&gt;&lt;p&gt;وتحتاج التطبيقات التي تسمح برفع ملفات حساسة إلى فحوص إضافية بحسب طبيعة الاستخدام، مثل فحص البرمجيات الخبيثة أو إعادة معالجة الصور قبل نشرها.&lt;/p&gt;&lt;h3&gt;11. تحديث Laravel ومكتبات Composer باستمرار&lt;/h3&gt;&lt;p&gt;قد تحتوي إصدارات Laravel أو PHP أو الحزم الخارجية على ثغرات أمنية يتم اكتشافها بمرور الوقت.&lt;/p&gt;&lt;p&gt;لذلك، فإن تأخير التحديثات قد يعرض التطبيق لهجمات تستغل ثغرات معروفة، خصوصًا عندما تكون هناك وسائل استغلال منشورة للعامة.&lt;/p&gt;&lt;p&gt;ابدأ بفحص الحزم المستخدمة في المشروع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;composer audit
&lt;/pre&gt;
&lt;p&gt;ويمكنك معرفة إصدار Laravel المثبت عبر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan --version
&lt;/pre&gt;
&lt;p&gt;احرص على متابعة نشرات الأمان الرسمية، واستخدم إصدارات مدعومة من Laravel وPHP، وخطط للتحديثات بصورة دورية.&lt;/p&gt;&lt;p&gt;قبل تحديث الحزم في الإنتاج:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;راجع التغييرات والتوافق بين الإصدارات.&lt;/li&gt;&lt;li&gt;نفذ الاختبارات في بيئة منفصلة.&lt;/li&gt;&lt;li&gt;اختبر الوظائف الأساسية وتكاملات التطبيق.&lt;/li&gt;&lt;li&gt;احتفظ بخطة رجوع (Rollback) عند حدوث مشكلة.&lt;/li&gt;&lt;li&gt;أعد نشر التطبيق باستخدام عملية موثوقة ومراقبة.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لا تتجاهل تحذيرات Composer الأمنية، ولا تثبت حزمًا مجهولة لمجرد أنها توفر ميزة سريعة.&lt;/p&gt;&lt;h3&gt;12. ضبط صلاحيات الملفات والخادم&lt;/h3&gt;&lt;p&gt;يجب ألا يعمل تطبيق Laravel بصلاحيات أوسع مما يحتاج إليه. فالصلاحيات المفرطة قد تجعل اختراق جزء من التطبيق وسيلة للوصول إلى ملفات أخرى على الخادم.&lt;/p&gt;&lt;p&gt;احرص على أن يكون مجلد &lt;code&gt;public&lt;/code&gt; هو جذر الويب (Document Root)، وألا يكون مجلد المشروع بالكامل متاحًا للعرض من الإنترنت.&lt;/p&gt;&lt;p&gt;كذلك، يجب منح حساب تشغيل التطبيق صلاحيات الكتابة اللازمة فقط، عادةً في مجلدات التخزين والسجلات ومجلدات التخزين المؤقت ذات الصلة.&lt;/p&gt;&lt;p&gt;تجنب استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;chmod -R 777 .
&lt;/pre&gt;
&lt;p&gt;لأن هذا الأمر يمنح صلاحيات واسعة وغير مناسبة في كثير من بيئات الإنتاج.&lt;/p&gt;&lt;p&gt;بدلًا من ذلك، اضبط الملكية والصلاحيات وفقًا لمستخدم الويب ونظام التشغيل وطريقة النشر. لا توجد مجموعة واحدة من الصلاحيات تصلح لجميع الخوادم، لذا يجب اختبارها ضمن بيئتك.&lt;/p&gt;&lt;p&gt;وتأكد من منع الوصول العام إلى الملفات الحساسة والنسخ الاحتياطية وسجلات التطبيق وملفات الإعدادات.&lt;/p&gt;&lt;h3&gt;13. استخدام Security Headers لحماية المتصفح&lt;/h3&gt;&lt;p&gt;تساعد ترويسات الأمان (Security Headers) على تقليل بعض أنواع الهجمات، كما يمكن أن توفر طبقة حماية إضافية عند ضبطها بشكل صحيح.&lt;/p&gt;&lt;p&gt;من أهم الترويسات:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;code&gt;Content-Security-Policy&lt;/code&gt;: تحدد مصادر المحتوى التي يُسمح للمتصفح بتحميلها، ويمكن أن تساعد في الحد من تأثير بعض هجمات XSS.&lt;/li&gt;&lt;li&gt;&lt;code&gt;X-Content-Type-Options: nosniff&lt;/code&gt;: تمنع المتصفح من تخمين نوع المحتوى في حالات معينة.&lt;/li&gt;&lt;li&gt;&lt;code&gt;Strict-Transport-Security&lt;/code&gt;: تطلب من المتصفح استخدام HTTPS في الزيارات المستقبلية.&lt;/li&gt;&lt;li&gt;&lt;code&gt;Referrer-Policy&lt;/code&gt;: تتحكم في مقدار معلومات المرجع التي تُرسل عند الانتقال بين الصفحات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكن إضافة هذه الترويسات عبر إعدادات خادم الويب أو Middleware في Laravel. لكن يجب اختبار سياسة CSP بعناية؛ إذ قد تؤدي الإعدادات غير المناسبة إلى تعطيل ملفات JavaScript أو CSS الضرورية للتطبيق.&lt;/p&gt;&lt;p&gt;ولا تعتبر هذه الترويسات بديلًا عن إصلاح الثغرات البرمجية الأساسية، بل طبقة إضافية ضمن استراتيجية دفاع متعددة المستويات.&lt;/p&gt;&lt;h3&gt;14. حماية السجلات والنسخ الاحتياطية وقاعدة البيانات&lt;/h3&gt;&lt;p&gt;لا تقتصر الحماية على كتابة كود آمن، بل تشمل أيضًا كيفية تخزين البيانات ومراقبتها واستعادتها عند وقوع حادث أمني.&lt;/p&gt;&lt;p&gt;تأكد من تنفيذ نسخ احتياطية دورية لقاعدة البيانات والملفات المهمة، واحفظ النسخ في مكان منفصل ومقيد الصلاحيات. كما يجب تشفير النسخ التي تحتوي على بيانات حساسة عند الحاجة، واختبار عملية الاستعادة دوريًا.&lt;/p&gt;&lt;p&gt;وفي سجلات التطبيق:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;لا تسجل كلمات المرور أو رموز الوصول أو مفاتيح API.&lt;/li&gt;&lt;li&gt;تجنب تسجيل بيانات شخصية أكثر مما تحتاج إليه.&lt;/li&gt;&lt;li&gt;حدد من يستطيع الوصول إلى السجلات.&lt;/li&gt;&lt;li&gt;راقب الأنشطة غير المعتادة ومحاولات الدخول الفاشلة.&lt;/li&gt;&lt;li&gt;احتفظ بالسجلات وفق سياسة واضحة للمدة والحذف.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ويفضل استخدام حساب قاعدة بيانات بصلاحيات محدودة تتناسب مع احتياجات التطبيق بدلًا من استخدام حساب إداري كامل في التشغيل اليومي.&lt;/p&gt;&lt;p&gt;كذلك، ضع خطة للاستجابة للحوادث الأمنية تتضمن عزل الأنظمة المتأثرة، وتدوير الأسرار المكشوفة، والتحقق من سلامة النسخ الاحتياطية، وتوثيق الحادث، وإصلاح السبب الأساسي قبل إعادة الخدمة.&lt;/p&gt;&lt;h3&gt;15. استخدام الاختبارات الأمنية والمراجعة المستمرة&lt;/h3&gt;&lt;p&gt;حتى مع اتباع جميع الممارسات السابقة، لا يمكن ضمان خلو التطبيق من الثغرات. لذلك، من المهم دمج الفحوص الأمنية في دورة التطوير.&lt;/p&gt;&lt;p&gt;يمكنك البدء بالخطوات التالية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;كتابة اختبارات للتحقق من أن المستخدم لا يستطيع الوصول إلى بيانات مستخدم آخر.&lt;/li&gt;&lt;li&gt;اختبار الصلاحيات في مسارات الإدارة والعمليات الحساسة.&lt;/li&gt;&lt;li&gt;تشغيل &lt;code&gt;composer audit&lt;/code&gt; ضمن عملية التكامل المستمر (CI).&lt;/li&gt;&lt;li&gt;مراجعة إعدادات الإنتاج قبل كل إصدار.&lt;/li&gt;&lt;li&gt;إجراء مراجعات للكود الذي يتعامل مع رفع الملفات والاستعلامات وتسجيل الدخول.&lt;/li&gt;&lt;li&gt;استخدام أدوات فحص ثابت للكود واختبارات أمنية مناسبة للمشروع.&lt;/li&gt;&lt;li&gt;إجراء اختبار اختراق مصرح به عند الحاجة، خصوصًا للتطبيقات التي تتعامل مع بيانات مالية أو شخصية حساسة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يجب أن تكون اختبارات الأمان جزءًا متكررًا من العمل، لا خطوة تنفذ مرة واحدة عند إطلاق الموقع.&lt;/p&gt;&lt;h3&gt;قائمة مراجعة سريعة لتأمين Laravel قبل النشر&lt;/h3&gt;&lt;p&gt;قبل نشر تطبيقك على خادم الإنتاج، راجع هذه القائمة:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;
 ضبط APP_DEBUG=false.
  &lt;/li&gt;
  &lt;li&gt;
التأكد من عدم كشف ملف .env أو أي أسرار أخرى.
  &lt;/li&gt;
  &lt;li&gt;استخدام HTTPS وشهادة TLS صالحة.
  &lt;/li&gt;
  &lt;li&gt;
    التأكد من حماية النماذج من CSRF عند الحاجة.
  &lt;/li&gt;
  &lt;li&gt;التحقق من المدخلات على الخادم.
  &lt;/li&gt;&lt;li&gt;استخدام Eloquent أو الاستعلامات المجهزة لتقليل مخاطر SQL Injection.
  &lt;/li&gt;
  &lt;li&gt;
  تقييد الحقول القابلة للتعبئة ومنع Mass Assignment.
  &lt;/li&gt;
  &lt;li&gt;
  تطبيق Authorization على كل مورد وعملية حساسة.
  &lt;/li&gt;
  &lt;li&gt;
    حماية تسجيل الدخول وتفعيل Rate Limiting.
  &lt;/li&gt;
  &lt;li&gt;
  التحقق من الملفات المرفوعة وتقييد أنواعها وأحجامها.
  &lt;/li&gt;
  &lt;li&gt;
 تحديث Laravel وPHP والحزم الخارجية.
  &lt;/li&gt;
  &lt;li&gt;
  ضبط صلاحيات الملفات ومجلدات المشروع.
  &lt;/li&gt;
  &lt;li&gt;
تقييد صلاحيات حساب قاعدة البيانات.
  &lt;/li&gt;
  &lt;li&gt;
إعداد النسخ الاحتياطية ومراقبة السجلات.
  &lt;/li&gt;
  &lt;li&gt;
  تنفيذ اختبارات أمنية قبل النشر وبعد التحديثات المهمة.
  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;إن حماية تطبيقات Laravel من الاختراق تعتمد على مجموعة متكاملة من الممارسات الأمنية، وليس على إعداد واحد أو حزمة برمجية واحدة. فتعطيل وضع التصحيح، وحماية ملف &lt;code&gt;.env&lt;/code&gt;، واستخدام HTTPS، والتحقق من المدخلات، وتطبيق الصلاحيات، وحماية الجلسات، وتحديث المكتبات، وضبط الخادم، كلها عناصر تساعد على تقليل فرص الاختراق وآثاره.&lt;/p&gt;&lt;p&gt;ابدأ بتطبيق الإجراءات الأساسية على مشروعك الحالي، ثم أضف الاختبارات والمراقبة والتحديثات المستمرة إلى دورة التطوير والنشر. وكلما كان الأمان جزءًا من تصميم التطبيق منذ البداية، أصبح اكتشاف المشكلات ومعالجتها أسهل وأقل تكلفة.&lt;/p&gt;&lt;p&gt;تذكر أن الهدف ليس الادعاء بأن التطبيق أصبح محصنًا تمامًا، بل تقليل سطح الهجوم، ومنع الأخطاء الشائعة، والاستعداد للتعامل مع الحوادث عند حدوثها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ملاحظة:&lt;/strong&gt; تختلف بعض التفاصيل البرمجية بحسب إصدار Laravel وطريقة إعداد التطبيق. راجع الوثائق الرسمية للإصدار الذي تستخدمه، واختبر أي تعديل أمني في بيئة غير إنتاجية قبل تطبيقه على الموقع الفعلي.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;المصادر والمراجع&lt;/b&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://laravel.com/framework/docs/csrf"&gt;Laravel Documentation – CSRF Protection&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Laravel_Cheat_Sheet.html"&gt;OWASP Laravel Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://cheatsheetseries.owasp.org/cheatsheets/Secrets_Management_Cheat_Sheet.html"&gt;OWASP Secrets Management Cheat Sheet&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://laravel.com/docs/sanctum"&gt;Laravel Sanctum Documentation&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/laravel/framework/security"&gt;Laravel Framework Security Advisories&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;</content><link href="https://www.nusurtech.ca/feeds/7280728781523529852/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/laravel-security-best-practices.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/7280728781523529852" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/7280728781523529852" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/laravel-security-best-practices.html" rel="alternate" title="أهم الممارسات الأمنية Security Best Practices لحماية تطبيقات Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAjcLvik__plAv0JytbgEbjG3Kqmb3wGu6h0VPrQvPGgKNEskN5iDEKG7OlMqJSNYs6IPlw8ls50drJDxqlY4iowx_lfjsSH1PSqhdts00YaKVir7GC_E0fspEhALtzfM9LYKU8FSs6XY5i05TozsNMMyuwSHdnPf_dF4s6meIlPOVM47JMuh567ZoGnOD/s72-c/imageedit_1_2890659900.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-7102352595665715382</id><published>2026-10-21T11:20:03.737+03:00</published><updated>2026-10-21T11:20:03.737+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">هل تفكر في بدء التداول؟ ولا تعرف من أين تبدأ؟</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9p4lO8yVuSrUzD5IkwYNn-tvHsU8a5Wypjdv3vJNksqlikTIsTGGLSZ8OAPDoUjzEBl2kua7ncxJ_c8axLID3g2E5sURaFXMFA49VITce2BFRUBRyeU3ex-KXEZViTGOnSJeYLqMtZ0L00rH9O8_jrVmFb3z9GyaMPDn9LcuCA-p6Ig7tRwwaL5JBddy4/s640/imageedit_1_9774080087.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="هل تفكر في بدء التداول؟ ولا تعرف من أين تبدأ؟" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9p4lO8yVuSrUzD5IkwYNn-tvHsU8a5Wypjdv3vJNksqlikTIsTGGLSZ8OAPDoUjzEBl2kua7ncxJ_c8axLID3g2E5sURaFXMFA49VITce2BFRUBRyeU3ex-KXEZViTGOnSJeYLqMtZ0L00rH9O8_jrVmFb3z9GyaMPDn9LcuCA-p6Ig7tRwwaL5JBddy4/s1600/imageedit_1_9774080087.webp" title="هل تفكر في بدء التداول؟ ولا تعرف من أين تبدأ؟" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;هل تفكر في بدء التداول؟ ولا تعرف من أين تبدأ؟&lt;/h3&gt;&lt;p&gt;هل تفكر في دخول عالم &lt;strong&gt;التداول&lt;/strong&gt;، وتسمع يوميًا عن أشخاص يحققون أرباحًا من شراء وبيع &lt;a href="https://www.investor.gov/introduction-investing" target="_blank"&gt;العملات&lt;/a&gt; والأسهم والذهب؟ هل ترغب في تعلم كيفية الاستفادة من الأسواق المالية، لكنك تشعر بالحيرة بسبب كثرة المعلومات والمصطلحات و &lt;a href="https://www.esma.europa.eu/investor-corner/get-ready-invest" target="_blank"&gt;المنصات&lt;/a&gt; المتاحة على الإنترنت؟&lt;/p&gt;&lt;p&gt;لا تقلق، فأنت لست وحدك. يبدأ معظم المتداولين الجدد بالأسئلة نفسها: ما هو التداول؟ كيف أبدأ من الصفر؟ كم أحتاج من المال؟ ما أفضل سوق للتداول؟ وكيف أتجنب الوقوع في فخ الشركات الوهمية والوعود بالأرباح السريعة؟&lt;/p&gt;&lt;p&gt;في هذا المقال، سنشرح لك أساسيات &lt;a href="https://www.investor.gov/protect-your-investments" target="_blank"&gt;التداول&lt;/a&gt; خطوة بخطوة، بداية من فهم الفكرة الأساسية، مرورًا باختيار السوق المناسب والتعلم والتدريب، وصولًا إلى كيفية إدارة المخاطر واختيار &lt;a href="https://www.nusurtech.ca/2026/10/what-is-trading.html"&gt;منصة موثوقة&lt;/a&gt;. والهدف هو أن تمتلك صورة واضحة قبل اتخاذ أي قرار يتعلق بأموالك.&lt;/p&gt;&lt;h3&gt;ما هو التداول وكيف يعمل؟&lt;/h3&gt;&lt;p&gt;التداول هو عملية شراء أصل مالي وبيعه بهدف الاستفادة من تغير سعره. قد يكون هذا الأصل سهمًا في شركة، أو عملة أجنبية، أو ذهبًا، أو سلعة، أو أصلًا رقميًا مثل العملات المشفرة.&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا اشتريت سهمًا بسعر 50 دولارًا ثم ارتفع سعره إلى 60 دولارًا وبعته، فإن ربحك الإجمالي يكون 10 دولارات عن كل سهم، قبل خصم الرسوم والتكاليف. أما إذا انخفض سعر السهم إلى 40 دولارًا وبعته، فستتحمل خسارة قدرها 10 دولارات عن كل سهم.&lt;/p&gt;&lt;p&gt;هذه هي الفكرة الأساسية للتداول، لكن الواقع أكثر تعقيدًا؛ فالأسعار تتغير باستمرار نتيجة الأخبار الاقتصادية، وقرارات البنوك المركزية، ونتائج الشركات، والعرض والطلب، والأحداث السياسية وغيرها من العوامل.&lt;/p&gt;&lt;p&gt;ومن المهم أن تعرف أن التداول لا يضمن تحقيق الأرباح، وأن المتداول قد يخسر جزءًا من رأس ماله أو كله في بعض الظروف، خصوصًا عند استخدام الرافعة المالية أو اتخاذ قرارات غير مدروسة.&lt;/p&gt;&lt;h3&gt;لماذا يرغب الكثيرون في تعلم التداول؟&lt;/h3&gt;&lt;p&gt;هناك أسباب متعددة تدفع الأشخاص إلى الاهتمام بالتداول، من بينها الرغبة في فهم الأسواق المالية، أو تنويع مصادر الدخل، أو الاستفادة من تحركات الأسعار، أو تطوير مهارات التحليل واتخاذ القرارات.&lt;/p&gt;&lt;p&gt;لكن من الضروري التمييز بين تعلم التداول باعتباره مهارة تحتاج إلى الوقت والانضباط، وبين الاعتقاد بأنه وسيلة سريعة للثراء.&lt;/p&gt;&lt;p&gt;فالتداول ليس وظيفة تضمن راتبًا شهريًا، ولا توجد استراتيجية تحقق أرباحًا في جميع الظروف. وحتى المتداولون أصحاب الخبرة يمرون بفترات خسارة، وقد يتعرضون لخسائر كبيرة إذا لم يلتزموا بإدارة المخاطر.&lt;/p&gt;&lt;p&gt;لذلك، إذا كنت ترغب في دخول هذا المجال، فاجعل هدفك الأول هو التعلم وحماية رأس المال، وليس تحقيق أرباح كبيرة في أسرع وقت ممكن.&lt;/p&gt;&lt;h3&gt;ما هي أهم الأسواق المالية التي يمكنك التداول فيها؟&lt;/h3&gt;&lt;p&gt;قبل اختيار منصة التداول، من الأفضل أن تتعرف على أشهر الأسواق المالية، لأن لكل سوق طبيعة مختلفة ومستوى خاصًا من المخاطر.&lt;/p&gt;&lt;h3&gt;1. سوق الأسهم&lt;/h3&gt;&lt;p&gt;يتيح لك سوق الأسهم شراء وبيع حصص في الشركات المدرجة في البورصات. وتتأثر أسعار الأسهم بأداء الشركات، وأرباحها، وتوقعات المستثمرين، والأوضاع الاقتصادية العامة.&lt;/p&gt;&lt;p&gt;قد يكون هذا السوق مناسبًا لمن يرغب في تعلم تحليل الشركات ومتابعة نتائجها المالية. ومع ذلك، فإن أسعار الأسهم يمكن أن تنخفض بصورة كبيرة، ولا توجد ضمانات بأن الشركة ستحقق أداءً جيدًا في المستقبل.&lt;/p&gt;&lt;p&gt;كما يجب التمييز بين الاستثمار طويل الأجل في الأسهم والتداول قصير الأجل؛ فلكل منهما أهداف واستراتيجيات ومخاطر مختلفة.&lt;/p&gt;&lt;h3&gt;2. سوق الفوركس&lt;/h3&gt;&lt;p&gt;الفوركس هو سوق تداول العملات الأجنبية، مثل اليورو والدولار الأمريكي والجنيه الإسترليني. ويتعامل المتداولون فيه مع أزواج العملات، مثل EUR/USD، ويحاولون الاستفادة من تغير سعر عملة مقابل أخرى.&lt;/p&gt;&lt;p&gt;يتأثر سوق الفوركس بأسعار الفائدة، وقرارات البنوك المركزية، والتضخم، والبيانات الاقتصادية، والأحداث السياسية.&lt;/p&gt;&lt;p&gt;ومن أبرز المخاطر في هذا السوق استخدام الرافعة المالية، التي تسمح بفتح صفقات أكبر من رأس المال المتاح. ورغم أنها قد تضخم الأرباح المحتملة، فإنها تضخم الخسائر أيضًا، وقد تؤدي إلى خسارة الأموال بسرعة.&lt;/p&gt;&lt;h3&gt;3. سوق الذهب والمعادن&lt;/h3&gt;&lt;p&gt;يُعد الذهب من الأصول التي يتابعها كثير من المتداولين والمستثمرين. ويتأثر سعره بعوامل مثل قوة الدولار، وأسعار الفائدة، والطلب العالمي، والتوترات الاقتصادية والسياسية.&lt;/p&gt;&lt;p&gt;يمكن التعرض لتحركات أسعار الذهب بطرق مختلفة، منها شراء الذهب الفعلي أو التعامل مع منتجات مالية مرتبطة بسعره. وهذه الطرق ليست متطابقة من حيث الرسوم والمخاطر وطبيعة الملكية.&lt;/p&gt;&lt;p&gt;لذلك، عليك فهم المنتج الذي تتعامل معه جيدًا قبل استثمار أموالك.&lt;/p&gt;&lt;h3&gt;4. سوق العملات المشفرة&lt;/h3&gt;&lt;p&gt;يشمل هذا السوق أصولًا رقمية مثل البيتكوين والإيثيريوم. وتتميز العملات المشفرة بتقلبات سعرية قد تكون حادة خلال فترات قصيرة، كما توجد مخاطر تتعلق بالمنصات والحفظ والاحتيال والتغيرات التنظيمية.&lt;/p&gt;&lt;p&gt;قد يحقق بعض المتداولين أرباحًا من تحركات أسعارها، لكنهم قد يتكبدون خسائر كبيرة أيضًا. ولهذا السبب، لا يُنصح المبتدئ بالتعامل معها على أنها فرصة مضمونة للربح.&lt;/p&gt;&lt;h3&gt;كيف تبدأ التداول من الصفر؟ خطوات عملية للمبتدئين&lt;/h3&gt;&lt;p&gt;إذا كنت لا تعرف من أين تبدأ، فلا تحتاج إلى فتح حساب حقيقي أو إيداع المال فورًا. يمكنك اتباع خطوات منظمة تساعدك على بناء أساس جيد قبل المخاطرة بأموالك.&lt;/p&gt;&lt;h3&gt;الخطوة الأولى: تعلم أساسيات التداول&lt;/h3&gt;&lt;p&gt;ابدأ بفهم المصطلحات الأساسية التي ستصادفها باستمرار، مثل:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;سعر الشراء وسعر البيع:&lt;/strong&gt; السعر الذي يمكنك الشراء أو البيع عنده وفقًا لشروط السوق والمنصة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;السبريد:&lt;/strong&gt; الفرق بين سعر الشراء وسعر البيع.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;الرافعة المالية:&lt;/strong&gt; وسيلة تتيح التعرض لمركز مالي أكبر من المبلغ المودع، مع زيادة المخاطر.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;وقف الخسارة:&lt;/strong&gt; أمر يُستخدم لمحاولة إغلاق الصفقة عند مستوى محدد لتقليل الخسارة، لكنه لا يضمن دائمًا التنفيذ بالسعر المحدد.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;جني الأرباح:&lt;/strong&gt; أمر لإغلاق الصفقة عند مستوى ربح مستهدف، مع مراعاة ظروف التنفيذ.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;التقلبات:&lt;/strong&gt; مقدار وسرعة تغير الأسعار خلال فترة معينة.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;خصص وقتًا منتظمًا للتعلم، واعتمد على مصادر تعليمية واضحة، وتجنب من يبيعون لك أوهام الربح المضمون أو الاستراتيجيات السرية التي لا تخطئ.&lt;/p&gt;&lt;h3&gt;الخطوة الثانية: اختر سوقًا واحدًا لتبدأ به&lt;/h3&gt;&lt;p&gt;من الأخطاء الشائعة محاولة تعلم جميع الأسواق في وقت واحد. فالمبتدئ الذي يتنقل يوميًا بين الأسهم والفوركس والذهب والعملات المشفرة قد يجد صعوبة في فهم العوامل التي تؤثر في كل سوق.&lt;/p&gt;&lt;p&gt;اختر سوقًا واحدًا، وابدأ بدراسة آلية عمله وأوقات التداول والرسوم والعوامل المؤثرة في الأسعار.&lt;/p&gt;&lt;p&gt;لا يوجد سوق هو الأفضل للجميع؛ فالاختيار يعتمد على خبرتك وأهدافك وقدرتك على تحمل المخاطر والمنتجات المتاحة في بلدك.&lt;/p&gt;&lt;h3&gt;الخطوة الثالثة: تعلم التحليل الأساسي والفني&lt;/h3&gt;&lt;p&gt;يعتمد التحليل الأساسي على دراسة العوامل الاقتصادية والمالية التي قد تؤثر في قيمة الأصل. ففي الأسهم، يمكن دراسة نتائج الشركة وأرباحها وديونها، بينما يمكن في سوق العملات متابعة أسعار الفائدة والتضخم والبيانات الاقتصادية.&lt;/p&gt;&lt;p&gt;أما التحليل الفني، فيعتمد على دراسة الرسوم البيانية وحركة الأسعار والأحجام والمؤشرات الفنية لمحاولة تحديد الاتجاهات والمستويات المهمة.&lt;/p&gt;&lt;p&gt;يمكن استخدام النوعين معًا، لكن يجب أن تعرف أن أي تحليل لا يقدم توقعات مؤكدة، وأن المؤشرات الفنية لا تضمن نجاح الصفقات.&lt;/p&gt;&lt;p&gt;ابدأ بالمفاهيم البسيطة، ولا تملأ الرسم البياني بعشرات المؤشرات التي لا تفهم طريقة عملها.&lt;/p&gt;&lt;h3&gt;الخطوة الرابعة: تدرب على حساب تجريبي&lt;/h3&gt;&lt;p&gt;قبل استخدام أموال حقيقية، يمكنك تجربة حساب تداول تجريبي إذا كان متاحًا لدى المنصة التي تختارها.&lt;/p&gt;&lt;p&gt;يتيح لك الحساب التجريبي التدرب على فتح الصفقات وإغلاقها واستخدام أوامر وقف الخسارة ومراقبة حركة الأسعار، عادةً باستخدام أموال افتراضية.&lt;/p&gt;&lt;p&gt;لكن تذكر أن التداول التجريبي لا يعكس دائمًا التجربة الحقيقية بالكامل؛ فالتعامل مع المال الحقيقي قد يسبب ضغطًا نفسيًا مختلفًا، كما قد تختلف ظروف التنفيذ والسيولة والرسوم.&lt;/p&gt;&lt;p&gt;استخدم الحساب التجريبي لتتعلم آلية المنصة وتختبر خطتك، وليس لإثبات أنك قادر على تحقيق أرباح مضمونة.&lt;/p&gt;&lt;h3&gt;الخطوة الخامسة: ضع خطة تداول واضحة&lt;/h3&gt;&lt;p&gt;خطة التداول هي مجموعة من القواعد التي تحدد متى تدخل الصفقة، ومتى تخرج منها، وكيف تتعامل مع الخسارة، وما مقدار المخاطرة التي يمكنك تحملها.&lt;/p&gt;&lt;p&gt;يمكن أن تتضمن خطتك الأسئلة التالية:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;ما السبب الذي يدفعني إلى دخول الصفقة؟&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ما السعر أو الشرط الذي يجعلني أخرج إذا لم يتحقق توقعي؟&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ما مقدار الخسارة المحتملة قبل فتح الصفقة؟&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;هل توجد أخبار اقتصادية مهمة قد تؤثر في السوق؟&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;هل ألتزم بالخطة أم أتخذ قرارات بسبب الخوف والطمع؟&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;دوّن صفقاتك في سجل خاص، وسجّل أسباب الدخول والخروج والنتيجة والأخطاء التي ارتكبتها. تساعدك هذه العادة على تقييم قراراتك بدلًا من الاعتماد على الذاكرة والانطباعات.&lt;/p&gt;&lt;h3&gt;الخطوة السادسة: لا تبدأ بأموال لا تستطيع تحمل خسارتها&lt;/h3&gt;&lt;p&gt;إذا قررت الانتقال إلى التداول الحقيقي بعد التعلم والتدريب، فلا تستخدم أموال الإيجار أو الفواتير أو المصاريف الأساسية أو صندوق الطوارئ.&lt;/p&gt;&lt;p&gt;تجنب أيضًا الاقتراض من أجل التداول، ولا تفترض أن الأرباح المستقبلية ستغطي التزاماتك الحالية.&lt;/p&gt;&lt;p&gt;ابدأ فقط بمبلغ يمكنك تحمل خسارته دون التأثير في احتياجاتك الأساسية. وحتى عند استخدام مبلغ صغير، يجب أن تفهم الرسوم والمخاطر وشروط المنتج المالي الذي تتعامل معه.&lt;/p&gt;&lt;h3&gt;كيف تختار منصة تداول موثوقة؟&lt;/h3&gt;&lt;p&gt;اختيار المنصة خطوة أساسية، لأن التعامل مع جهة غير موثوقة قد يعرض أموالك وبياناتك للخطر. لا تعتمد على الإعلانات أو عدد المتابعين أو توصيات المؤثرين وحدها.&lt;/p&gt;&lt;p&gt;قبل فتح الحساب، تحقق من النقاط التالية:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. الترخيص والجهة الرقابية:&lt;/strong&gt; ابحث عن الاسم القانوني للشركة ورقم ترخيصها، ثم تحقق منه مباشرة عبر الموقع الرسمي للجهة الرقابية. لا تكتفِ بصورة ترخيص منشورة على موقع الشركة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. صلاحية الخدمة في بلدك:&lt;/strong&gt; قد يختلف الترخيص والمنتج المتاح والحماية القانونية بحسب بلد إقامتك والكيان الذي يفتح حسابك لديه.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. الرسوم والتكاليف:&lt;/strong&gt; اقرأ تفاصيل السبريد والعمولات ورسوم الإيداع والسحب وتكاليف الاحتفاظ بالصفقات وأي رسوم أخرى.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. شروط السحب:&lt;/strong&gt; افهم إجراءات سحب الأموال والمدة المتوقعة والرسوم ومتطلبات التحقق من الهوية قبل إيداع أي مبلغ.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5. حماية الحساب والبيانات:&lt;/strong&gt; تحقق من وسائل الأمان، واستخدم كلمة مرور قوية ومختلفة، وفعّل المصادقة متعددة العوامل إن كانت متاحة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;6. وضوح المعلومات:&lt;/strong&gt; يجب أن تكون شروط الخدمة والمخاطر والمنتجات المالية واضحة ومفهومة، وألا تعتمد الشركة على وعود بأرباح مضمونة.&lt;/p&gt;&lt;p&gt;تذكر أن وجود موقع احترافي أو تطبيق سهل الاستخدام لا يثبت وحده أن الشركة موثوقة. كما أن الترخيص لا يلغي مخاطر التداول ولا يضمن الربح.&lt;/p&gt;&lt;h3&gt;كيف تتجنب شركات التداول النصابة؟&lt;/h3&gt;&lt;p&gt;تنتشر على الإنترنت إعلانات تدعي القدرة على مضاعفة رأس المال خلال أيام أو تحقيق دخل يومي ثابت من دون خبرة. وقد تستخدم بعض الجهات صورًا لأشخاص مشهورين أو شهادات عملاء غير حقيقية لإقناع المبتدئين بإيداع الأموال.&lt;/p&gt;&lt;p&gt;انتبه إلى العلامات التحذيرية التالية:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;وعود بأرباح مضمونة أو خالية من المخاطر.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ضغط مستمر عليك لإيداع الأموال بسرعة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;طلب تحويل الأموال إلى حساب شخصي أو محفظة لا تستطيع التحقق من ملكيتها.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;صعوبة سحب الأموال أو اختلاق رسوم إضافية غير واضحة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;ادعاء وجود ترخيص لا يمكن التحقق منه عبر الجهة الرقابية الرسمية.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;طلب بيانات الدخول إلى حسابك أو التحكم في جهازك عن بُعد دون مبرر موثوق.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;إذا واجهت إحدى هذه العلامات، فتوقف عن تحويل الأموال، وتحقق من الشركة بشكل مستقل. وإذا كنت قد أرسلت أموالًا بالفعل وتشك في تعرضك للاحتيال، فتواصل سريعًا مع البنك أو مزود الدفع والجهة الرقابية المختصة في بلدك، واحتفظ بالمراسلات والإيصالات.&lt;/p&gt;&lt;h3&gt;ما هي إدارة المخاطر ولماذا تعتبر أهم من الأرباح؟&lt;/h3&gt;&lt;p&gt;قد ينشغل المبتدئ بالبحث عن أفضل استراتيجية أو مؤشر، لكنه يتجاهل السؤال الأهم: ماذا سيحدث إذا كانت الصفقة خاطئة؟&lt;/p&gt;&lt;p&gt;إدارة المخاطر تعني وضع حدود للخسائر المحتملة وتجنب تعريض رأس المال كله لصفقة واحدة.&lt;/p&gt;&lt;p&gt;من المبادئ الأساسية لإدارة المخاطر:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;لا تضع كامل رأس مالك في صفقة واحدة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;تجنب استخدام الرافعة المالية قبل فهم طريقة عملها ومخاطرها.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;حدد مسبقًا مقدار الخسارة الذي يمكنك تحمله.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;لا تضاعف حجم الصفقة لمجرد تعويض خسارة سابقة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;لا تدخل السوق بدافع الانتقام من صفقة خاسرة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;لا تعتمد على مصدر واحد للمعلومات أو على توصيات مجهولة.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;ومن المهم أن تعرف أن وقف الخسارة لا يمنع جميع الخسائر؛ فقد يتحرك السعر بسرعة أو تحدث فجوة سعرية، ما يؤدي إلى تنفيذ الأمر بسعر مختلف عن المستوى المحدد.&lt;/p&gt;&lt;p&gt;الهدف من إدارة المخاطر ليس منع الخسارة تمامًا، فهذا غير ممكن، وإنما تقليل احتمال أن تؤدي خسارة واحدة أو سلسلة من الخسائر إلى ضرر مالي كبير.&lt;/p&gt;&lt;h3&gt;أخطاء شائعة يقع فيها المبتدئون في التداول&lt;/h3&gt;&lt;p&gt;هناك مجموعة من الأخطاء التي قد تجعل تجربة التداول أصعب وأكثر تكلفة، ومن أبرزها:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;التداول دون خطة:&lt;/strong&gt; الدخول في الصفقات لمجرد أن السعر يتحرك بسرعة قد يؤدي إلى قرارات عشوائية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الطمع والرغبة في الربح السريع:&lt;/strong&gt; محاولة مضاعفة المال خلال فترة قصيرة قد تدفع المتداول إلى تحمل مخاطر أكبر مما يستطيع تحمله.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تقليد الآخرين دون فهم:&lt;/strong&gt; قد ينشر شخص توصية تبدو ناجحة، لكنك لا تعرف ظروفه المالية أو حجم المخاطرة التي يتحملها أو ما إذا كانت التوصية تناسبك.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;إهمال الرسوم:&lt;/strong&gt; قد تؤثر تكاليف التداول المتكررة في النتيجة النهائية، حتى عندما تبدو بعض الصفقات ناجحة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخلط بين الحظ والمهارة:&lt;/strong&gt; تحقيق ربح في صفقة واحدة لا يعني بالضرورة أن الاستراتيجية فعالة. تحتاج إلى تقييم منظم لعدد كافٍ من الصفقات مع مراعاة المخاطر والتكاليف.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;التداول تحت الضغط النفسي:&lt;/strong&gt; الخوف والطمع والقلق قد تؤدي إلى مخالفة الخطة. لذلك، فإن الراحة والانضباط وتحديد وقت للتوقف عوامل مهمة أيضًا.&lt;/p&gt;&lt;h3&gt;هل التداول مناسب للجميع؟&lt;/h3&gt;&lt;p&gt;ليس بالضرورة. يعتمد مدى ملاءمة التداول على وضعك المالي وأهدافك وخبرتك وقدرتك على تحمل الخسائر والوقت الذي تستطيع تخصيصه للتعلم والمتابعة.&lt;/p&gt;&lt;p&gt;إذا كنت تحتاج إلى المال قريبًا لتغطية مصاريف أساسية، أو لا تستطيع تحمل خسارة المبلغ الذي تفكر في إيداعه، فقد يكون من الأفضل تأجيل التداول والتركيز على بناء استقرار مالي مناسب أولًا.&lt;/p&gt;&lt;p&gt;ومن المهم كذلك التمييز بين التداول النشط والاستثمار طويل الأجل والادخار. فلكل خيار أهداف مختلفة، وقد لا يكون التداول قصير الأجل مناسبًا لشخص لا يملك الوقت أو الرغبة في متابعة الأسواق.&lt;/p&gt;&lt;p&gt;لا توجد طريقة مالية واحدة تناسب الجميع، ومن الأفضل اتخاذ القرار بناءً على ظروفك الحقيقية لا على قصص الأرباح التي تراها على الإنترنت.&lt;/p&gt;&lt;h3&gt;خطة بسيطة لتعلم التداول خلال أول 30 يومًا&lt;/h3&gt;&lt;p&gt;يمكنك البدء بخطة تعليمية أولية تساعدك على تنظيم وقتك، مع العلم أن هذه المدة ليست كافية بالضرورة لتصبح متداولًا محترفًا.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الأسبوع الأول: فهم الأساسيات&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تعرف على الأسواق المالية المختلفة، ومفهوم العرض والطلب، والفرق بين الاستثمار والتداول، ومعاني المصطلحات الأساسية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الأسبوع الثاني: تعلم قراءة الأسعار&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ابدأ بالتعرف على الرسوم البيانية والاتجاهات ومستويات الدعم والمقاومة، وادرس بعض العوامل الاقتصادية التي تؤثر في السوق الذي اخترته.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الأسبوع الثالث: التدريب العملي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم حسابًا تجريبيًا إن توفر، وتدرب على تنفيذ الصفقات وتحديد نقاط الدخول والخروج وتسجيل النتائج.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الأسبوع الرابع: مراجعة الأداء وإدارة المخاطر&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;راجع صفقاتك التجريبية، وحدد الأخطاء المتكررة، واكتب خطة تداول واضحة. لا تنتقل إلى التداول الحقيقي لمجرد انتهاء الشهر؛ انتقل فقط عندما تفهم المخاطر وتستطيع شرح قواعدك وسبب استخدامك لها.&lt;/p&gt;&lt;h3&gt;الخلاصة: كيف تبدأ التداول بطريقة صحيحة؟&lt;/h3&gt;&lt;p&gt;إذا كنت تفكر في بدء التداول ولا تعرف من أين تبدأ، فالحل ليس البحث عن منصة تعدك بالأرباح، بل اتباع خطوات واضحة: تعلم الأساسيات، واختر سوقًا تفهمه، وتدرب على حساب تجريبي، وضع خطة تداول، وتعلم إدارة المخاطر، وتحقق من ترخيص الشركة قبل إيداع الأموال.&lt;/p&gt;&lt;p&gt;تذكر أن النجاح في هذا المجال لا يقاس بربح صفقة واحدة، بل بقدرتك على اتخاذ قرارات مدروسة وفهم المخاطر والالتزام بخطة مناسبة لظروفك.&lt;/p&gt;&lt;p&gt;لا تستعجل النتائج، ولا تسمح للإعلانات أو قصص الثراء السريع بأن تدفعك إلى المخاطرة بأموال تحتاج إليها. اجعل التعلم أولويتك، وتذكر دائمًا أن رأس مالك يستحق الحماية قبل البحث عن الأرباح.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تنبيه مهم:&lt;/strong&gt; هذا المقال لأغراض تعليمية وتثقيفية فقط، ولا يُعد نصيحة استثمارية أو توصية بشراء أو بيع أي أصل مالي. التداول ينطوي على مخاطر، وقد تخسر جزءًا من أموالك أو كامل المبلغ المستثمر. ادرس ظروفك المالية واستعن بمختص مرخص عند الحاجة قبل اتخاذ قرارات استثمارية.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/7102352595665715382/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/thinking-of-starting-trading.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/7102352595665715382" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/7102352595665715382" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/thinking-of-starting-trading.html" rel="alternate" title="هل تفكر في بدء التداول؟ ولا تعرف من أين تبدأ؟" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg9p4lO8yVuSrUzD5IkwYNn-tvHsU8a5Wypjdv3vJNksqlikTIsTGGLSZ8OAPDoUjzEBl2kua7ncxJ_c8axLID3g2E5sURaFXMFA49VITce2BFRUBRyeU3ex-KXEZViTGOnSJeYLqMtZ0L00rH9O8_jrVmFb3z9GyaMPDn9LcuCA-p6Ig7tRwwaL5JBddy4/s72-c/imageedit_1_9774080087.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-1595470832389940964</id><published>2026-10-21T09:42:40.058+03:00</published><updated>2026-10-21T09:42:40.058+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">تقسيم النتائج والتصفية والبحث في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Nk0ADjxeaKFl_vVzRng1_RVtvfHJD3yXnBHZE5GCRnpOhN-IVgD-INW98dDC_m_EbT0MAcRis_vFF3PHZoHIWAcE2Y0pC77V65SO0YET3S_-l4gEch7z8ZEXqPym708ib2xI30RsIJy4SYAnoLOEW6g7ooiW3CnX6yGGbF_QHBkq1YnN9ckcnFVdH0fq/s640/imageedit_1_7326198886.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="تقسيم النتائج إلى صفحات، وتصفية البيانات حسب شروط معينة، وإضافة خاصية البحث داخل قاعدة البيانات" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Nk0ADjxeaKFl_vVzRng1_RVtvfHJD3yXnBHZE5GCRnpOhN-IVgD-INW98dDC_m_EbT0MAcRis_vFF3PHZoHIWAcE2Y0pC77V65SO0YET3S_-l4gEch7z8ZEXqPym708ib2xI30RsIJy4SYAnoLOEW6g7ooiW3CnX6yGGbF_QHBkq1YnN9ckcnFVdH0fq/s1600/imageedit_1_7326198886.webp" title="تقسيم النتائج إلى صفحات، وتصفية البيانات حسب شروط معينة، وإضافة خاصية البحث داخل قاعدة البيانات" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;h3&gt;تقسيم النتائج والتصفية والبحث Pagination وFiltering وSearching في Laravel&lt;/h3&gt;&lt;p&gt;عندما تبدأ في بناء تطبيق باستخدام Laravel، قد تحتاج إلى عرض المقالات أو المنتجات أو المستخدمين الموجودين في قاعدة البيانات. في البداية، ربما تستخدم &lt;code&gt;Article::all()&lt;/code&gt; لجلب جميع المقالات وعرضها داخل الصفحة، لكن ماذا سيحدث عندما يحتوي موقعك على آلاف المقالات أو مئات الآلاف من المنتجات؟&lt;/p&gt;&lt;p&gt;عرض جميع النتائج دفعة واحدة قد يؤدي إلى بطء الصفحة واستهلاك موارد الخادم، كما يجعل تصفح البيانات صعبًا على المستخدم. لذلك توفر Laravel أدوات تساعدك على تقسيم النتائج إلى صفحات، وتصفية البيانات حسب شروط معينة، والبحث عن سجلات محددة.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنتعلم ثلاثة مفاهيم أساسية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;Pagination:&lt;/strong&gt; تقسيم النتائج إلى صفحات صغيرة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Filtering:&lt;/strong&gt; تصفية النتائج وفق شروط، مثل التصنيف أو الحالة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Searching:&lt;/strong&gt; البحث عن كلمة داخل عنوان المقال أو محتواه.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;سنطبق هذه المفاهيم على نظام المقالات الذي استخدمناه في الدروس السابقة، بالاعتماد على Eloquent ORM وControllers وBlade Templates. ويمكنك مراجعة &lt;a href="https://laravel.com/framework/docs/13.x/pagination"&gt;توثيق Laravel الرسمي الخاص بالترقيم&lt;/a&gt; و&lt;a href="https://laravel.com/framework/docs/13.x/queries"&gt;Query Builder&lt;/a&gt; للتوسع في هذه الموضوعات.&lt;/p&gt;&lt;h3&gt;أولًا: ما المقصود بـ Pagination؟&lt;/h3&gt;&lt;p&gt;Pagination هي عملية تقسيم مجموعة كبيرة من النتائج إلى صفحات متعددة بدلًا من عرضها جميعًا في صفحة واحدة.&lt;/p&gt;&lt;p&gt;تخيل أن موقعك يحتوي على 500 مقال، وتريد عرض 10 مقالات فقط في كل صفحة. بدلًا من عرض المقالات الخمسمائة دفعة واحدة، ستعرض أول 10 مقالات، ثم تتيح للمستخدم الانتقال إلى الصفحة التالية لعرض المقالات التالية.&lt;/p&gt;&lt;p&gt;تساعد هذه الطريقة على:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;تحسين تجربة المستخدم.&lt;/li&gt;&lt;li&gt;تقليل عدد السجلات التي تُعرض في كل صفحة.&lt;/li&gt;&lt;li&gt;تنظيم النتائج وتسهيل تصفحها.&lt;/li&gt;&lt;li&gt;تجنب تحميل مجموعة ضخمة من البيانات وعرضها دفعة واحدة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;توفر Laravel عدة طرق للترقيم، أهمها &lt;code&gt;paginate()&lt;/code&gt; و&lt;code&gt;simplePaginate()&lt;/code&gt; و&lt;code&gt;cursorPaginate()&lt;/code&gt;، ولكل طريقة استخدام يناسب نوع التطبيق وحجم البيانات. &lt;a href="https://laravel.com/framework/docs/13.x/pagination"&gt;المصدر الرسمي&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لماذا لا نستخدم all() دائمًا؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكنك جلب جميع المقالات بهذه الطريقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::all();
&lt;/pre&gt;
&lt;p&gt;لكن هذه الطريقة تجلب جميع السجلات المطابقة من قاعدة البيانات، ثم تحتفظ بالنتائج في الذاكرة. وقد يكون ذلك غير مناسب عندما يكبر حجم البيانات.&lt;/p&gt;&lt;p&gt;أما عند استخدام &lt;code&gt;paginate()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::paginate(10);
&lt;/pre&gt;
&lt;p&gt;فإن Laravel تجلب مجموعة النتائج الخاصة بالصفحة الحالية، وتوفر معلومات عن عدد الصفحات والنتائج الإجمالية، حتى تتمكن من إنشاء روابط التنقل بينها.&lt;/p&gt;&lt;h3&gt;ثانيًا: إنشاء Pagination باستخدام paginate()&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;الخطوة الأولى: تجهيز Controller&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;افتح Controller الخاص بالمقالات، أو أنشئ واحدًا جديدًا إذا لم يكن موجودًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:controller ArticleController
&lt;/pre&gt;
&lt;p&gt;افتح الملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
app/Http/Controllers/ArticleController.php
&lt;/pre&gt;
&lt;p&gt;ثم أضف الكود التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\View\View;

class ArticleController extends Controller
{
    public function index(): View
    {
        $articles = Article::latest()-&amp;gt;paginate(10);

        return view('articles.index', compact('articles'));
    }
}
&lt;/pre&gt;
&lt;p&gt;شرح الكود:&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;code&gt;Article::latest()&lt;/code&gt; يرتب المقالات من الأحدث إلى الأقدم اعتمادًا على &lt;code&gt;created_at&lt;/code&gt; افتراضيًا.&lt;/li&gt;&lt;li&gt;&lt;code&gt;paginate(10)&lt;/code&gt; يقسم النتائج إلى صفحات، بحيث تعرض كل صفحة 10 مقالات كحد أقصى.&lt;/li&gt;&lt;li&gt;&lt;code&gt;compact('articles')&lt;/code&gt; يمرر متغير المقالات إلى صفحة Blade.&lt;/li&gt;&lt;li&gt;&lt;code&gt;view('articles.index')&lt;/code&gt; يعرض ملف الواجهة المطلوب.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;إذا كان جدول المقالات يحتوي على 47 مقالًا، فسيكون عدد الصفحات خمس صفحات عند عرض 10 مقالات في كل صفحة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثانية: إنشاء Route&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;افتح الملف &lt;code&gt;routes/web.php&lt;/code&gt; وأضف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Http\Controllers\ArticleController;
use Illuminate\Support\Facades\Route;

Route::get('/articles', [ArticleController::class, 'index'])
    -&amp;gt;name('articles.index');
&lt;/pre&gt;
&lt;p&gt;أصبح بإمكان المستخدم الوصول إلى قائمة المقالات عبر الرابط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
http://localhost:8000/articles
&lt;/pre&gt;&lt;p&gt;وعند الانتقال إلى الصفحة الثانية، ستضيف Laravel معامل الصفحة إلى عنوان الرابط، مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
http://localhost:8000/articles?page=2
&lt;/pre&gt;&lt;p&gt;تتعامل Laravel مع هذا المعامل تلقائيًا عند استخدام &lt;code&gt;paginate()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثالثة: عرض المقالات في Blade&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ الملف التالي إذا لم يكن موجودًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
resources/views/articles/index.blade.php
&lt;/pre&gt;&lt;p&gt;ثم أضف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="ar" dir="rtl"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;المقالات&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;قائمة المقالات&amp;lt;/h1&amp;gt;

    @forelse ($articles as $article)
        &amp;lt;article&amp;gt;
            &amp;lt;h2&amp;gt;{{ $article-&amp;gt;title }}&amp;lt;/h2&amp;gt;

            &amp;lt;p&amp;gt;
                {{ $article-&amp;gt;content }}
            &amp;lt;/p&amp;gt;

            &amp;lt;small&amp;gt;
                {{ $article-&amp;gt;created_at?-&amp;gt;format('Y-m-d') }}
            &amp;lt;/small&amp;gt;
        &amp;lt;/article&amp;gt;

        &amp;lt;hr&amp;gt;
    @empty
        &amp;lt;p&amp;gt;لا توجد مقالات لعرضها.&amp;lt;/p&amp;gt;
    @endforelse

    {{ $articles-&amp;gt;links() }}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;السطر الأهم في هذا المثال هو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;{{ $articles-&amp;gt;links() }}
&lt;/pre&gt;
&lt;p&gt;تستخدم Laravel هذه الدالة لعرض روابط التنقل بين الصفحات. ويعتمد الشكل الافتراضي لهذه الروابط على Tailwind CSS، لذلك قد تحتاج إلى تنسيقها إذا كنت تستخدم إطار CSS آخر أو تصميمًا مخصصًا.&lt;/p&gt;&lt;h3&gt;ثالثًا: الفرق بين paginate() وsimplePaginate() وcursorPaginate()&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;1. استخدام paginate()&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::paginate(10);
&lt;/pre&gt;
&lt;p&gt;تُستخدم عندما تريد عرض روابط الصفحات مع معرفة العدد الإجمالي للنتائج وعدد الصفحات.&lt;/p&gt;&lt;p&gt;وهي مناسبة لقوائم المقالات والمنتجات وصفحات الإدارة التي تحتاج إلى معرفة عدد الصفحات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. استخدام simplePaginate()&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::simplePaginate(10);
&lt;/pre&gt;
&lt;p&gt;تُستخدم عندما تحتاج إلى روابط الصفحة التالية والسابقة فقط، ولا تحتاج إلى معرفة العدد الإجمالي للنتائج.&lt;/p&gt;&lt;p&gt;قد تكون أكثر كفاءة في بعض الحالات لأنها لا تنفذ استعلام حساب العدد الإجمالي للنتائج بالطريقة التي تستخدمها &lt;code&gt;paginate()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. استخدام cursorPaginate()&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::orderBy('id')-&amp;gt;cursorPaginate(10);
&lt;/pre&gt;
&lt;p&gt;تستخدم هذه الطريقة مؤشرًا للتنقل بين النتائج بدلًا من الاعتماد على أرقام الصفحات التقليدية. وقد تكون مناسبة لقوائم البيانات الكبيرة جدًا أو واجهات التحميل المستمر.&lt;/p&gt;&lt;p&gt;تتطلب هذه الطريقة ترتيبًا مناسبًا، ويجب أن تكون أعمدة الترتيب مؤهلة لدعم التصفح بالمؤشر، مثل استخدام عمود فريد أو مجموعة أعمدة تضمن ترتيبًا فريدًا. كما أنها لا توفر روابط لجميع أرقام الصفحات بالطريقة التقليدية.&lt;/p&gt;&lt;p&gt;لذلك، ابدأ باستخدام &lt;code&gt;paginate()&lt;/code&gt; في تطبيقك، وانتقل إلى الطرق الأخرى عندما تكون هناك حاجة فعلية إليها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;رابعًا: ما المقصود بـ Filtering؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Filtering يعني تصفية النتائج وفق شروط محددة يختارها المستخدم أو يفرضها التطبيق.&lt;/p&gt;&lt;p&gt;على سبيل المثال، في موقع المقالات قد تريد عرض:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;المقالات المنشورة فقط.&lt;/li&gt;&lt;li&gt;المقالات التابعة إلى تصنيف محدد.&lt;/li&gt;&lt;li&gt;المقالات التي أُنشئت خلال فترة زمنية معينة.&lt;/li&gt;&lt;li&gt;المقالات التي كتبها مستخدم محدد.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكنك تنفيذ هذه الشروط باستخدام Eloquent وطرق مثل &lt;code&gt;where()&lt;/code&gt; و&lt;code&gt;when()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال: تصفية المقالات حسب الحالة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنفترض أن جدول المقالات يحتوي على عمود اسمه &lt;code&gt;status&lt;/code&gt;، وقيمته إما &lt;code&gt;published&lt;/code&gt; أو &lt;code&gt;draft&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;يمكنك جلب المقالات المنشورة فقط باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('status', 'published')
    -&amp;gt;latest()
    -&amp;gt;paginate(10);
&lt;/pre&gt;
&lt;p&gt;هنا لن تعرض Laravel إلا المقالات التي تحقق الشرط، ثم تقسم النتائج المطابقة إلى صفحات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ملاحظة:&lt;/strong&gt; يجب أن يكون عمود &lt;code&gt;status&lt;/code&gt; موجودًا فعلًا في جدول المقالات. إذا لم يكن موجودًا، فيجب إضافته من خلال Migration وتحديث بنية قاعدة البيانات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال: التصفية حسب اختيار المستخدم&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنفترض أنك تريد السماح للمستخدم باختيار حالة المقال من خلال الرابط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
/articles?status=published
&lt;/pre&gt;
&lt;p&gt;يمكنك قراءة قيمة الحالة من الطلب، ثم استخدامها في الاستعلام.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function index()
{
    $status = request('status');

    $articles = Article::query()
        -&amp;gt;when($status, function ($query, $status) {
            $query-&amp;gt;where('status', $status);
        })
        -&amp;gt;latest()
        -&amp;gt;paginate(10);

    return view('articles.index', compact('articles', 'status'));
}
&lt;/pre&gt;
&lt;p&gt;تعمل &lt;code&gt;when()&lt;/code&gt; على تطبيق الشرط فقط عندما تكون قيمة &lt;code&gt;$status&lt;/code&gt; موجودة وصادقة وفق تقييم PHP.&lt;/p&gt;&lt;p&gt;لكن في التطبيقات الحقيقية، يجب ألا نسمح للمستخدم بإرسال أي قيمة عشوائية إذا كانت الحالات محددة مسبقًا. لذلك يمكن التحقق من القيمة أولًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$status = request('status');

if (! in_array($status, ['published', 'draft'], true)) {
    $status = null;
}
&lt;/pre&gt;&lt;p&gt;بعد ذلك يمكنك استخدام &lt;code&gt;$status&lt;/code&gt; في الاستعلام السابق.&lt;/p&gt;&lt;p&gt;هذا المثال بسيط للتعلم، أما عند بناء تطبيق أكبر، فيمكن تنظيم التحقق من مدخلات التصفية باستخدام Validation أو Form Request.&lt;/p&gt;&lt;h3&gt;إنشاء نموذج تصفية في Blade&lt;/h3&gt;&lt;p&gt;أضف النموذج التالي قبل قائمة المقالات في ملف &lt;code&gt;articles/index.blade.php&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form action="{{ route('articles.index') }}" method="GET"&amp;gt;
    &amp;lt;label for="status"&amp;gt;حالة المقال:&amp;lt;/label&amp;gt;

    &amp;lt;select name="status" id="status"&amp;gt;
        &amp;lt;option value=""&amp;gt;جميع المقالات&amp;lt;/option&amp;gt;

        &amp;lt;option value="published"
            @selected(($status ?? '') === 'published')&amp;gt;
            منشور
        &amp;lt;/option&amp;gt;

        &amp;lt;option value="draft"
            @selected(($status ?? '') === 'draft')&amp;gt;
            مسودة
        &amp;lt;/option&amp;gt;
    &amp;lt;/select&amp;gt;

    &amp;lt;button type="submit"&amp;gt;تصفية&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;p&gt;استخدمنا &lt;code&gt;GET&lt;/code&gt; لأننا نريد تمرير خيارات البحث والتصفية ضمن عنوان الصفحة. وهذا يسمح بمشاركة رابط النتائج مع شخص آخر أو إعادة فتحه لاحقًا.&lt;/p&gt;&lt;h3&gt;خامسًا: ما المقصود بـ Searching؟&lt;/h3&gt;&lt;p&gt;Searching هو البحث عن كلمة أو عبارة داخل البيانات.&lt;/p&gt;&lt;p&gt;في موقع المقالات، قد يكتب المستخدم كلمة مثل &lt;code&gt;Laravel&lt;/code&gt;، ويريد رؤية المقالات التي تحتوي عناوينها أو محتوياتها على هذه الكلمة.&lt;/p&gt;&lt;p&gt;يمكننا استخدام &lt;code&gt;where()&lt;/code&gt; مع شرط &lt;code&gt;LIKE&lt;/code&gt;، أو استخدام &lt;code&gt;whereLike()&lt;/code&gt; في إصدارات Laravel التي تدعم هذه الطريقة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال: البحث داخل عنوان المقال&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$search = request('search');

$articles = Article::query()
    -&amp;gt;when($search, function ($query, $search) {
        $query-&amp;gt;whereLike('title', "%{$search}%");
    })
    -&amp;gt;latest()
    -&amp;gt;paginate(10);
&lt;/pre&gt;
&lt;p&gt;في هذا المثال:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;code&gt;request('search')&lt;/code&gt; تقرأ عبارة البحث من الطلب.&lt;/li&gt;&lt;li&gt;&lt;code&gt;whereLike()&lt;/code&gt; تبحث عن العبارة داخل عمود العنوان.&lt;/li&gt;&lt;li&gt;علامتا &lt;code&gt;%&lt;/code&gt; تسمحان بوجود نص قبل الكلمة أو بعدها.&lt;/li&gt;&lt;li&gt;&lt;code&gt;paginate(10)&lt;/code&gt; يقسم نتائج البحث إلى صفحات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا كتب المستخدم &lt;code&gt;Laravel&lt;/code&gt;، فسيظهر أي مقال يحتوي عنوانه على هذه الكلمة.&lt;/p&gt;&lt;p&gt;وتوفر Laravel طرقًا أخرى مثل &lt;code&gt;orWhereLike()&lt;/code&gt; للبحث في أعمدة متعددة، مع إمكانية التحكم في حساسية حالة الأحرف بحسب الحاجة. راجع &lt;a href="https://laravel.com/framework/docs/13.x/queries"&gt;توثيق Query Builder&lt;/a&gt; للتفاصيل.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;البحث في العنوان والمحتوى معًا&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;قد ترغب في البحث عن الكلمة داخل عنوان المقال أو محتواه. يمكننا تجميع شروط البحث داخل دالة واحدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$search = request('search');

$articles = Article::query()
    -&amp;gt;when($search, function ($query, $search) {
        $query-&amp;gt;where(function ($query) use ($search) {
            $query-&amp;gt;whereLike('title', "%{$search}%")
                -&amp;gt;orWhereLike('content', "%{$search}%");
        });
    })
    -&amp;gt;latest()
    -&amp;gt;paginate(10);
&lt;/pre&gt;
&lt;p&gt;استخدمنا &lt;code&gt;where()&lt;/code&gt; مع دالة داخلية لتجميع الشرطين منطقيًا. وهذا مهم حتى لا يؤثر شرط &lt;code&gt;OR&lt;/code&gt; في شروط أخرى قد نضيفها للاستعلام، مثل حالة النشر أو ملكية المقال.&lt;/p&gt;&lt;p&gt;إذا كنت تريد عرض المقالات المنشورة فقط والبحث داخلها، فستكون الصيغة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::query()
    -&amp;gt;where('status', 'published')
    -&amp;gt;when($search, function ($query, $search) {
        $query-&amp;gt;where(function ($query) use ($search) {
            $query-&amp;gt;whereLike('title', "%{$search}%")
                -&amp;gt;orWhereLike('content', "%{$search}%");
        });
    })
    -&amp;gt;latest()
    -&amp;gt;paginate(10);
&lt;/pre&gt;
&lt;p&gt;بهذه الطريقة، لا تظهر المسودات حتى لو كانت تحتوي على كلمة البحث.&lt;/p&gt;&lt;h3&gt;سادسًا: إنشاء نموذج البحث في Blade&lt;/h3&gt;&lt;p&gt;افتح الملف &lt;code&gt;resources/views/articles/index.blade.php&lt;/code&gt; وأضف نموذج البحث:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form action="{{ route('articles.index') }}" method="GET"&amp;gt;
    &amp;lt;label for="search"&amp;gt;ابحث عن مقال:&amp;lt;/label&amp;gt;

    &amp;lt;input
        type="search"
        name="search"
        id="search"
        value="{{ request('search') }}"
        placeholder="اكتب عنوان المقال..."
    &amp;gt;

    &amp;lt;button type="submit"&amp;gt;بحث&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;p&gt;لاحظ استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;value="{{ request('search') }}"
&lt;/pre&gt;
&lt;p&gt;هذا يجعل عبارة البحث السابقة تظهر داخل الحقل بعد إرسال النموذج، بدلًا من مطالبة المستخدم بكتابتها مرة أخرى.&lt;/p&gt;&lt;p&gt;ويمكنك الجمع بين البحث والتصفية داخل نموذج واحد، بحيث يختار المستخدم حالة المقال ويكتب كلمة البحث ثم يضغط على زر البحث.&lt;/p&gt;&lt;h3&gt;سابعًا: الحفاظ على خيارات البحث والتصفية عند الانتقال بين الصفحات&lt;/h3&gt;&lt;p&gt;هذه من أكثر النقاط التي يواجهها المبتدئون.&lt;/p&gt;&lt;p&gt;لنفترض أن المستخدم بحث عن كلمة &lt;code&gt;Laravel&lt;/code&gt;، وظهرت له عدة صفحات من النتائج. عندما ينتقل إلى الصفحة الثانية، يجب أن يبقى شرط البحث موجودًا حتى لا تظهر جميع المقالات بدلًا من النتائج المطابقة.&lt;/p&gt;&lt;p&gt;تتيح Laravel استخدام &lt;code&gt;withQueryString()&lt;/code&gt; للاحتفاظ بمعاملات الاستعلام الحالية عند إنشاء روابط الصفحات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::query()
    -&amp;gt;when($search, function ($query, $search) {
        $query-&amp;gt;whereLike('title', "%{$search}%");
    })
    -&amp;gt;latest()
    -&amp;gt;paginate(10)
    -&amp;gt;withQueryString();
&lt;/pre&gt;
&lt;p&gt;إذا كان الرابط يحتوي على:&lt;/p&gt;&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;/articles?search=Laravel&amp;amp;status=published&lt;/code&gt;&lt;/p&gt;&lt;p&gt;فستحتفظ روابط الصفحات بمعاملات الاستعلام الحالية.&lt;/p&gt;&lt;p&gt;يمكنك أيضًا استخدام &lt;code&gt;appends()&lt;/code&gt; لإضافة معاملات محددة يدويًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles-&amp;gt;appends([
    'search' =&amp;gt; $search,
    'status' =&amp;gt; $status,
]);
&lt;/pre&gt;
&lt;p&gt;استخدم طريقة واحدة مناسبة لحالتك؛ غالبًا ما تكون &lt;code&gt;withQueryString()&lt;/code&gt; أسهل عندما تريد الاحتفاظ بجميع خيارات البحث والتصفية الموجودة في الرابط.&lt;/p&gt;&lt;h3&gt;ثامنًا: بناء صفحة مقالات تجمع Pagination و Filtering و Searching&lt;/h3&gt;&lt;p&gt;سننشئ الآن مثالًا متكاملًا يجمع المفاهيم الثلاثة في Controller واحد.&lt;/p&gt;&lt;p&gt;يفترض المثال وجود Model باسم &lt;code&gt;Article&lt;/code&gt; وجدول يحتوي على الأعمدة &lt;code&gt;title&lt;/code&gt; و&lt;code&gt;content&lt;/code&gt; و&lt;code&gt;status&lt;/code&gt; و&lt;code&gt;created_at&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;كود Controller&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Http\Controllers;

use App\Models\Article;
use Illuminate\Http\Request;
use Illuminate\View\View;

class ArticleController extends Controller
{
    public function index(Request $request): View
    {
        $validated = $request-&amp;gt;validate([
            'search' =&amp;gt; ['nullable', 'string', 'max:100'],
            'status' =&amp;gt; ['nullable', 'in:published,draft'],
        ]);

        $search = $validated['search'] ?? null;
        $status = $validated['status'] ?? null;

        $articles = Article::query()
            -&amp;gt;when($search, function ($query, $search) {
                $query-&amp;gt;where(function ($query) use ($search) {
                    $query-&amp;gt;whereLike(
                        'title',
                        "%{$search}%"
                    )-&amp;gt;orWhereLike(
                        'content',
                        "%{$search}%"
                    );
                });
            })
            -&amp;gt;when($status, function ($query, $status) {
                $query-&amp;gt;where('status', $status);
            })
            -&amp;gt;latest()
            -&amp;gt;paginate(10)
            -&amp;gt;withQueryString();

        return view('articles.index', compact(
            'articles',
            'search',
            'status'
        ));
    }
}
&lt;/pre&gt;
&lt;p&gt;شرح ما يحدث:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;نتحقق من قيمة البحث حتى لا تتجاوز 100 حرف، ونسمح بغيابها.&lt;/li&gt;&lt;li&gt;نتحقق من أن الحالة إما &lt;code&gt;published&lt;/code&gt; أو &lt;code&gt;draft&lt;/code&gt; إذا أُرسلت.&lt;/li&gt;&lt;li&gt;نبني الاستعلام باستخدام &lt;code&gt;Article::query()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;نضيف شروط البحث عند وجود كلمة بحث.&lt;/li&gt;&lt;li&gt;نضيف شرط الحالة عند اختيار حالة معينة.&lt;/li&gt;&lt;li&gt;نرتب المقالات من الأحدث إلى الأقدم.&lt;/li&gt;&lt;li&gt;نقسم النتائج إلى صفحات، مع الاحتفاظ بخيارات البحث والتصفية.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;كود Blade&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكنك استخدام النموذج التالي في &lt;code&gt;resources/views/articles/index.blade.php&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="ar" dir="rtl"&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8"&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0"&amp;gt;
    &amp;lt;title&amp;gt;المقالات&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;المقالات&amp;lt;/h1&amp;gt;

    &amp;lt;form action="{{ route('articles.index') }}" method="GET"&amp;gt;
        &amp;lt;input
            type="search"
            name="search"
            value="{{ $search ?? '' }}"
            placeholder="ابحث في المقالات..."
        &amp;gt;

        &amp;lt;select name="status"&amp;gt;
            &amp;lt;option value=""&amp;gt;جميع الحالات&amp;lt;/option&amp;gt;

            &amp;lt;option value="published"
                @selected(($status ?? '') === 'published')&amp;gt;
                منشور
            &amp;lt;/option&amp;gt;

            &amp;lt;option value="draft"
                @selected(($status ?? '') === 'draft')&amp;gt;
                مسودة
            &amp;lt;/option&amp;gt;
        &amp;lt;/select&amp;gt;

        &amp;lt;button type="submit"&amp;gt;تطبيق&amp;lt;/button&amp;gt;

        &amp;lt;a href="{{ route('articles.index') }}"&amp;gt;مسح الفلاتر&amp;lt;/a&amp;gt;
    &amp;lt;/form&amp;gt;

    &amp;lt;hr&amp;gt;

    @forelse ($articles as $article)
        &amp;lt;article&amp;gt;
            &amp;lt;h2&amp;gt;{{ $article-&amp;gt;title }}&amp;lt;/h2&amp;gt;

            &amp;lt;p&amp;gt;{{ $article-&amp;gt;content }}&amp;lt;/p&amp;gt;

            &amp;lt;small&amp;gt;الحالة: {{ $article-&amp;gt;status }}&amp;lt;/small&amp;gt;
        &amp;lt;/article&amp;gt;

        &amp;lt;hr&amp;gt;
    @empty
        &amp;lt;p&amp;gt;لا توجد مقالات تطابق معايير البحث.&amp;lt;/p&amp;gt;
    @endforelse

    {{ $articles-&amp;gt;links() }}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;أصبح بإمكان المستخدم البحث عن كلمة، وتحديد حالة المقال، والتنقل بين صفحات النتائج مع الاحتفاظ بخياراته.&lt;/p&gt;&lt;h3&gt;تاسعًا: تحسين الأداء عند التعامل مع بيانات كثيرة&lt;/h3&gt;&lt;p&gt;عندما يكبر التطبيق، من المهم التفكير في كفاءة الاستعلامات، وليس فقط في صحة النتائج.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. لا تجلب جميع السجلات دون حاجة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم &lt;code&gt;paginate()&lt;/code&gt; بدلًا من &lt;code&gt;all()&lt;/code&gt; عندما تعرض قائمة كبيرة من السجلات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. اختر الأعمدة التي تحتاجها&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا لم تكن بحاجة إلى جميع أعمدة المقال، يمكنك تحديد المطلوب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::query()
    -&amp;gt;select(['id', 'title', 'created_at'])
    -&amp;gt;latest()
    -&amp;gt;paginate(10);
&lt;/pre&gt;
&lt;p&gt;تأكد من تضمين الأعمدة اللازمة للعلاقات أو وظائف الصفحة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. فكر في الفهارس Indexes&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كان البحث أو التصفية يعتمد على أعمدة معينة بصورة متكررة، فقد تساعد الفهارس في تحسين بعض الاستعلامات. لكن فائدتها تعتمد على نوع قاعدة البيانات وحجم البيانات وطبيعة الاستعلام.&lt;/p&gt;&lt;p&gt;كذلك، فإن استخدام &lt;code&gt;LIKE&lt;/code&gt; مع &lt;code&gt;%&lt;/code&gt; في بداية عبارة البحث، مثل &lt;code&gt;%Laravel%&lt;/code&gt;، قد يمنع الاستفادة من فهرس تقليدي في بعض قواعد البيانات. إذا كنت تحتاج إلى بحث متقدم على نطاق كبير، ففكر في حلول Full-Text Search المناسبة لقاعدة البيانات أو أدوات البحث المتخصصة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. لا تسمح للمستخدم بتحديد أعمدة الترتيب دون تحقق&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا أردت إضافة قائمة لترتيب المقالات حسب العنوان أو التاريخ، فلا تمرر اسم العمود القادم من المستخدم مباشرة إلى &lt;code&gt;orderBy()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;بدلًا من ذلك، استخدم قائمة مسموحًا بها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$allowedSorts = ['title', 'created_at'];

$sort = request('sort', 'created_at');

if (! in_array($sort, $allowedSorts, true)) {
    $sort = 'created_at';
}
$articles = Article::orderBy($sort, 'desc')
    -&amp;gt;paginate(10)
    -&amp;gt;withQueryString();
&lt;/pre&gt;
&lt;p&gt;تذكر أن أسماء الأعمدة لا تُحمى بالطريقة نفسها التي تُحمى بها قيم المقارنة عبر parameter binding؛ لذلك يجب تقييدها إلى خيارات موثوقة. &lt;a href="https://laravel.com/framework/docs/13.x/queries"&gt;توثيق Query Builder&lt;/a&gt;&lt;/p&gt;&lt;h3&gt;عاشرًا: أخطاء شائعة يجب تجنبها&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;الخطأ الأول: استخدام links() مع مجموعة عادية&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا جلبت النتائج باستخدام &lt;code&gt;all()&lt;/code&gt;، فلن تحصل على كائن Pagination الذي توفره &lt;code&gt;paginate()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;الحل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::paginate(10);
&lt;/pre&gt;
&lt;p&gt;ثم في Blade:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;{{ $articles-&amp;gt;links() }}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;الخطأ الثاني: فقدان البحث بعد تغيير الصفحة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;السبب هو عدم الاحتفاظ بمعاملات الاستعلام.&lt;/p&gt;&lt;p&gt;الحل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::paginate(10)-&amp;gt;withQueryString();
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;الخطأ الثالث: عدم تجميع شروط OR&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;قد يؤدي استخدام &lt;code&gt;orWhereLike()&lt;/code&gt; دون تجميع الشروط إلى ظهور نتائج لا تحقق بقية شروط الاستعلام.&lt;/p&gt;&lt;p&gt;الحل هو استخدام دالة داخلية مع &lt;code&gt;where()&lt;/code&gt; لتجميع شروط البحث.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطأ الرابع: نسيان التحقق من المدخلات&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لا تفترض أن المستخدم سيرسل قيمًا صحيحة دائمًا. استخدم Validation لتحديد نوع البيانات وطول عبارة البحث والقيم المسموح بها للتصفية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطأ الخامس: الاعتماد على LIKE لكل أنواع البحث&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;البحث البسيط مناسب لكثير من التطبيقات الصغيرة والمتوسطة، لكنه ليس دائمًا الخيار الأفضل للبحث الكامل داخل نصوص كبيرة أو لآلاف السجلات ذات متطلبات بحث متقدمة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الحادي عشر: تمرين عملي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;حان وقت التطبيق!&lt;/p&gt;&lt;p&gt;أنشئ صفحة لإدارة المقالات في مشروع Laravel الخاص بك، وطبّق المتطلبات التالية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;اعرض 10 مقالات في كل صفحة.&lt;/li&gt;&lt;li&gt;أضف حقلًا للبحث داخل عنوان المقال.&lt;/li&gt;&lt;li&gt;أضف قائمة لتصفية المقالات حسب الحالة.&lt;/li&gt;&lt;li&gt;اجعل البحث والتصفية يعملان معًا.&lt;/li&gt;&lt;li&gt;احتفظ بخيارات المستخدم عند الانتقال إلى الصفحة التالية.&lt;/li&gt;&lt;li&gt;أضف رابطًا لمسح جميع الفلاتر.&lt;/li&gt;&lt;li&gt;اعرض رسالة مناسبة إذا لم توجد نتائج.&lt;/li&gt;&lt;li&gt;تحقق من مدخلات المستخدم باستخدام Validation.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;بعد الانتهاء، جرّب البحث عن كلمة موجودة في عدة مقالات، ثم اختر حالة معينة، وانتقل إلى الصفحة التالية. تأكد من استمرار تطبيق الشروط نفسها.&lt;/p&gt;&lt;p&gt;تعلمنا في هذا الدرس كيفية تنظيم نتائج قاعدة البيانات باستخدام Pagination، وإنشاء شروط Filtering باستخدام &lt;code&gt;where()&lt;/code&gt; و&lt;code&gt;when()&lt;/code&gt;، وإضافة Searching باستخدام &lt;code&gt;whereLike()&lt;/code&gt; و&lt;code&gt;orWhereLike()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;كما أنشأنا صفحة متكاملة للمقالات تجمع البحث والتصفية والترقيم، وتعلمنا أهمية الاحتفاظ بمعاملات الاستعلام، والتحقق من المدخلات، وتحسين أداء الاستعلامات عند نمو التطبيق.&lt;/p&gt;&lt;p&gt;أصبحت لديك الآن الأدوات الأساسية لبناء صفحات القوائم في مواقع المقالات والمتاجر ولوحات التحكم.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;في الدرس السادس عشر&lt;/strong&gt;، سننتقل إلى موضوع مهم عند بناء تطبيقات Laravel، وهو &lt;strong&gt;إرسال البريد الإلكتروني (Mail) والإشعارات (Notifications)&lt;/strong&gt;، وكيفية إرسال رسائل للمستخدمين عند التسجيل أو نشر مقال أو حدوث حدث مهم داخل التطبيق.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/1595470832389940964/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/laravel-pagination-filtering-searching.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/1595470832389940964" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/1595470832389940964" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/laravel-pagination-filtering-searching.html" rel="alternate" title="تقسيم النتائج والتصفية والبحث في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Nk0ADjxeaKFl_vVzRng1_RVtvfHJD3yXnBHZE5GCRnpOhN-IVgD-INW98dDC_m_EbT0MAcRis_vFF3PHZoHIWAcE2Y0pC77V65SO0YET3S_-l4gEch7z8ZEXqPym708ib2xI30RsIJy4SYAnoLOEW6g7ooiW3CnX6yGGbF_QHBkq1YnN9ckcnFVdH0fq/s72-c/imageedit_1_7326198886.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-7095126041674796494</id><published>2026-10-19T10:55:35.977+03:00</published><updated>2026-10-19T10:55:35.977+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">ماهو التداول Trading وكيف ابدأ التداول وماهي الاسواق الموثوقة</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWB_XzegMRjoKBXSCrVr6G_PSrMk5aR32lYH1CtMqV2MifaKaL1aMiPkMNQ0krsE_cHa5M6FQ9G4MWHQcdrshhd4EL_zE8Q9-hXqLfobyypPBoQnirBxaZnTB6eRKGAQntuUQhIacS_Rn8WYRlGenc-dNyLq0s2G7akXImByps1VNfnWxTlMlCJVVP41Qq/s640/imageedit_1_9272739681.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="ماهو التداول Trading و كيف ابدأ التداول و ماهي الاسواق الموثوقة" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWB_XzegMRjoKBXSCrVr6G_PSrMk5aR32lYH1CtMqV2MifaKaL1aMiPkMNQ0krsE_cHa5M6FQ9G4MWHQcdrshhd4EL_zE8Q9-hXqLfobyypPBoQnirBxaZnTB6eRKGAQntuUQhIacS_Rn8WYRlGenc-dNyLq0s2G7akXImByps1VNfnWxTlMlCJVVP41Qq/s1600/imageedit_1_9272739681.webp" title="ماهو التداول Trading و كيف ابدأ التداول و ماهي الاسواق الموثوقة" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;ماهو التداول و كيف ابدأ التداول و ماهي الاسواق الموثوقة&lt;/h3&gt;&lt;p&gt;أصبح &lt;strong&gt;التداول&lt;/strong&gt; من الموضوعات التي تحظى باهتمام كبير في السنوات الأخيرة، خاصة مع انتشار الإنترنت وتطور &lt;strong&gt;التطبيقات المالية&lt;/strong&gt; التي تسمح للأفراد بشراء وبيع الأصول المالية من خلال الهاتف أو الكمبيوتر. يبحث الكثير من المبتدئين عن إجابة واضحة لسؤال: &lt;strong&gt;ما هو التداول؟&lt;/strong&gt; و &lt;strong&gt;كيف أبدأ التداول من الصفر؟&lt;/strong&gt; و &lt;strong&gt;ما هي الأسواق المالية الموثوقة التي يمكن التعامل معها بأمان؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;في الحقيقة، يمكن أن يكون التداول وسيلة للمشاركة في الأسواق المالية والاستفادة من تغيرات الأسعار، لكنه ليس طريقًا مضمونًا لتحقيق &lt;b&gt;الأرباح السريعة&lt;/b&gt;. فالتداول &lt;a href="https://www.nusurtech.ca/2026/08/what-is-trading.html" target="_blank"&gt;Trading&lt;/a&gt; يحتاج إلى المعرفة والتدريب وإدارة المخاطر، كما أن اختيار وسيط مالي مرخص ومنصة مناسبة يعد من أهم الخطوات التي يجب اتخاذها قبل استثمار أي أموال.&lt;/p&gt;&lt;p&gt;في هذا المقال، سنتعرف بالتفصيل على مفهوم التداول، وأنواعه، وأهم الأسواق المالية، وخطوات البدء من الصفر، بالإضافة إلى كيفية التمييز بين الشركات الموثوقة والمنصات الاحتيالية.&lt;/p&gt;&lt;h3&gt;ما هو التداول Trading ؟&lt;/h3&gt;&lt;p&gt;التداول هو عملية شراء وبيع الأصول المالية بهدف الاستفادة من تغير أسعارها خلال فترة زمنية معينة. وتشمل هذه الأصول الأسهم والعملات الأجنبية والذهب والنفط والمؤشرات المالية والعملات المشفرة، بحسب السوق والمنصة التي يتعامل معها المستثمر.&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا اشترى شخص سهمًا بسعر 50 دولارًا، ثم ارتفع سعره إلى 60 دولارًا وباعه، فإنه يحقق ربحًا قدره 10 دولارات عن كل سهم، قبل خصم العمولات والرسوم والضرائب إن وجدت. أما إذا انخفض سعر السهم إلى 40 دولارًا وباعه، فسيتكبد خسارة قدرها 10 دولارات عن كل سهم.&lt;/p&gt;&lt;p&gt;تبدو الفكرة بسيطة، لكن اتخاذ قرارات التداول في الواقع يحتاج إلى دراسة حركة الأسعار، وفهم العوامل الاقتصادية المؤثرة في الأسواق، وتحديد حجم المخاطرة المقبول.&lt;/p&gt;&lt;p&gt;ومن المهم التمييز بين التداول والاستثمار. فالمتداول غالبًا ما يركز على تحركات الأسعار خلال فترات قصيرة أو متوسطة، بينما يميل المستثمر طويل الأجل إلى الاحتفاظ بأصوله لفترات أطول بهدف الاستفادة من نموها أو الحصول على توزيعات الأرباح، بحسب طبيعة الأصل.&lt;/p&gt;&lt;h3&gt;كيف يعمل التداول في الأسواق المالية؟&lt;/h3&gt;&lt;p&gt;تعمل الأسواق المالية على أساس العرض والطلب. عندما يزداد الطلب على أصل معين مقارنة بالعرض المتاح، قد يرتفع سعره، بينما قد ينخفض السعر عندما يزداد ضغط البيع.&lt;/p&gt;&lt;p&gt;لكن الأسعار لا تتحرك بطريقة عشوائية تمامًا؛ إذ تتأثر بعوامل متعددة، مثل أسعار الفائدة والتضخم ونتائج الشركات والأحداث السياسية والاقتصادية وتوقعات المستثمرين.&lt;/p&gt;&lt;p&gt;يعتمد المتداول على تحليل هذه العوامل لاتخاذ قرارات البيع والشراء. ويمكن تقسيم التحليل إلى نوعين رئيسيين:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. التحليل الفني&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يعتمد التحليل الفني على دراسة الرسوم البيانية وحركة الأسعار وأحجام التداول، باستخدام أدوات مثل الاتجاهات ومستويات الدعم والمقاومة والمتوسطات المتحركة ومؤشرات الزخم.&lt;/p&gt;&lt;p&gt;يساعد هذا النوع من التحليل على تنظيم قرارات التداول وتحديد نقاط الدخول والخروج المحتملة، لكنه لا يستطيع التنبؤ بالأسعار بصورة مؤكدة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. التحليل الأساسي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يركز التحليل الأساسي على دراسة العوامل الاقتصادية والمالية التي قد تؤثر في قيمة الأصول. فعند تحليل الأسهم، يمكن دراسة إيرادات الشركة وأرباحها وديونها وخطط نموها. أما في سوق العملات، فقد يهتم المتداول بأسعار الفائدة ومعدلات التضخم وبيانات التوظيف والسياسات النقدية للبنوك المركزية.&lt;/p&gt;&lt;p&gt;يمكن الجمع بين التحليل الفني والأساسي للحصول على صورة أشمل، مع إدراك أن أي تحليل لا يلغي احتمالية الخسارة.&lt;/p&gt;&lt;h3&gt;ما هي أهم أنواع التداول؟&lt;/h3&gt;&lt;p&gt;توجد عدة أنواع من التداول تختلف بحسب مدة الاحتفاظ بالصفقات وطبيعة الأصول المتداولة والاستراتيجية المستخدمة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;1. التداول اليومي&lt;/h4&gt;&lt;p&gt;التداول اليومي هو شراء الأصول وبيعها خلال اليوم نفسه، وغالبًا ما يغلق المتداول صفقاته قبل نهاية جلسة التداول.&lt;/p&gt;&lt;p&gt;يحتاج هذا النوع إلى متابعة مستمرة للأسعار وسرعة في اتخاذ القرارات، وقد يتضمن عددًا كبيرًا من الصفقات والعمولات. لذلك، لا يناسب بالضرورة جميع المبتدئين، خصوصًا من لا يملكون الوقت أو الخبرة الكافية.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;2. التداول المتأرجح&lt;/h4&gt;&lt;p&gt;يعتمد التداول المتأرجح، المعروف باسم Swing Trading، على الاحتفاظ بالصفقات لعدة أيام أو أسابيع للاستفادة من تحركات الأسعار المتوسطة.&lt;/p&gt;&lt;p&gt;قد يكون مناسبًا للأشخاص الذين لا يستطيعون مراقبة السوق طوال اليوم، لكنه يتطلب الصبر والقدرة على تحمل التقلبات التي تحدث أثناء الاحتفاظ بالصفقات.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;3. التداول طويل الأجل&lt;/h4&gt;&lt;p&gt;في هذا الأسلوب، يحتفظ المتداول أو المستثمر بالأصل لفترة طويلة نسبيًا، وقد تمتد المدة لأشهر أو سنوات، بحسب الهدف والاستراتيجية.&lt;/p&gt;&lt;p&gt;وعلى الرغم من أن هذا الأسلوب يرتبط غالبًا بالاستثمار طويل الأجل أكثر من التداول السريع، فإنه قد يناسب من يفضلون تقليل عدد قرارات البيع والشراء والتركيز على قيمة الأصول على المدى الطويل.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;4. تداول العقود مقابل الفروقات&lt;/h4&gt;&lt;p&gt;العقود مقابل الفروقات، أو CFD، هي منتجات مالية تسمح بالمضاربة على تغير سعر أصل معين دون امتلاكه بالضرورة.&lt;/p&gt;&lt;p&gt;قد توفر هذه العقود إمكانية الاستفادة من ارتفاع الأسعار أو انخفاضها وفقًا لشروط المنتج، لكنها تنطوي على مخاطر مرتفعة، خصوصًا عند استخدام الرافعة المالية. كما تختلف القيود والحماية القانونية المتاحة من دولة إلى أخرى.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;5. تداول العملات المشفرة&lt;/h4&gt;&lt;p&gt;يشمل تداول العملات المشفرة شراء وبيع أصول رقمية مثل البيتكوين والإيثيريوم، من خلال منصات متخصصة.&lt;/p&gt;&lt;p&gt;تتميز هذه السوق بالتقلبات الكبيرة وإمكانية التداول على مدار الساعة في العديد من المنصات، لكنها تواجه أيضًا مخاطر تتعلق بالأمن الإلكتروني والاحتيال والسيولة والتغيرات التنظيمية. لذلك، يجب عدم التعامل معها باعتبارها استثمارًا مضمونًا أو مناسبًا لجميع الأشخاص.&lt;/p&gt;&lt;h3&gt;ما هي أهم الأسواق المالية التي يمكن التداول فيها؟&lt;/h3&gt;&lt;p&gt;قبل البدء في التداول، من الضروري معرفة طبيعة الأسواق المختلفة، لأن لكل سوق خصائصه ومخاطره وتكاليفه.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;أولًا: سوق الأسهم&lt;/h4&gt;&lt;p&gt;سوق الأسهم هو السوق الذي يتم فيه شراء وبيع حصص الملكية في الشركات المدرجة في البورصات.&lt;/p&gt;&lt;p&gt;يمكن للمستثمر شراء أسهم شركات تعمل في مجالات التكنولوجيا والصناعة والطاقة والصحة وغيرها. وتتأثر أسعار الأسهم بأداء الشركات وأرباحها وتوقعات النمو والأوضاع الاقتصادية العامة.&lt;/p&gt;&lt;p&gt;من أشهر البورصات العالمية بورصة نيويورك وناسداك وبورصة لندن وبورصة طوكيو.&lt;/p&gt;&lt;p&gt;يتميز سوق الأسهم بوجود شركات خاضعة لمتطلبات الإفصاح والرقابة بحسب السوق، لكن ذلك لا يعني أن جميع الأسهم آمنة أو أن الاستثمار فيها يضمن الربح.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ثانيًا: سوق الفوركس&lt;/h4&gt;&lt;p&gt;الفوركس هو سوق تداول العملات الأجنبية، مثل اليورو مقابل الدولار الأمريكي أو الجنيه الإسترليني مقابل الدولار.&lt;/p&gt;&lt;p&gt;يستفيد المتداول في هذا السوق من تغير أسعار الصرف بين العملات. ويتأثر السوق بقرارات البنوك المركزية وأسعار الفائدة والبيانات الاقتصادية والتطورات السياسية.&lt;/p&gt;&lt;p&gt;يعد الفوركس من الأسواق ذات السيولة المرتفعة في أزواج العملات الرئيسية، لكن تداول الفوركس عبر منتجات الرافعة المالية قد يؤدي إلى خسائر كبيرة، وقد تتجاوز الخسائر المبلغ المتوقع بحسب نوع المنتج والقواعد المطبقة.&lt;/p&gt;&lt;p&gt;لهذا السبب، ينبغي للمبتدئ فهم الرافعة المالية والهامش وتكاليف التبييت وفروق الأسعار قبل فتح أي صفقة حقيقية.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ثالثًا: سوق الذهب والمعادن الثمينة&lt;/h4&gt;&lt;p&gt;يحظى الذهب باهتمام كبير لدى المتداولين والمستثمرين، لأنه يتأثر بعوامل مثل أسعار الفائدة وقوة الدولار والتوترات الجيوسياسية والطلب على المعدن.&lt;/p&gt;&lt;p&gt;يمكن التعرض لأسعار الذهب من خلال شراء الذهب المادي أو بعض الصناديق المتداولة أو العقود المالية التي تقدمها الجهات المرخصة.&lt;/p&gt;&lt;p&gt;لكن هذه الخيارات ليست متطابقة؛ فالذهب المادي قد يتضمن تكاليف التخزين والبيع، بينما قد تنطوي المنتجات المالية والمشتقات على مخاطر إضافية تتعلق بالرافعة المالية والجهة المقدمة للمنتج.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;رابعًا: سوق النفط والسلع&lt;/h4&gt;&lt;p&gt;تشمل أسواق السلع النفط والغاز الطبيعي والفضة والنحاس والقمح وغيرها من المواد الأولية.&lt;/p&gt;&lt;p&gt;تتأثر أسعارها بالعرض والطلب والإنتاج العالمي والمخزونات والأحداث الجيوسياسية والظروف المناخية.&lt;/p&gt;&lt;p&gt;وقد تكون هذه الأسواق شديدة التقلب، خاصة عند حدوث أزمات في الإمدادات أو تغيرات مفاجئة في الطلب. لذلك، ينبغي فهم طبيعة كل سلعة والأداة المالية المستخدمة للتداول عليها.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;خامسًا: سوق المؤشرات المالية&lt;/h4&gt;&lt;p&gt;المؤشر المالي يقيس أداء مجموعة من الأسهم وفقًا لقواعد محددة. ومن الأمثلة المعروفة مؤشر S&amp;amp;P 500 ومؤشر ناسداك المركب ومؤشر داو جونز.&lt;/p&gt;&lt;p&gt;يمكن أن تتيح بعض المنتجات المالية المضاربة على حركة المؤشرات أو الاستثمار فيها بصورة غير مباشرة، مثل بعض الصناديق المتداولة.&lt;/p&gt;&lt;p&gt;يساعد التنويع داخل المؤشر على تقليل الاعتماد على شركة واحدة، لكنه لا يمنع خسائر السوق العامة، كما أن طريقة الاستثمار أو التداول في المؤشر تؤثر في مستوى المخاطرة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;سادسًا: سوق العملات المشفرة&lt;/h4&gt;&lt;p&gt;تضم هذه السوق أصولًا رقمية تعتمد على تقنيات مختلفة، وتختلف في استخداماتها وآليات إصدارها ومستويات السيولة المتاحة لها.&lt;/p&gt;&lt;p&gt;قبل التعامل مع أي منصة للعملات المشفرة، يجب التحقق من الوضع التنظيمي للمنصة في الدولة المعنية، وطريقة حفظ الأصول، وسياسات السحب، وإجراءات حماية الحساب.&lt;/p&gt;&lt;p&gt;كما ينبغي الحذر من العملات مجهولة المشروع والمنصات التي تعد بأرباح مضمونة أو تطلب تحويل الأموال إلى محافظ شخصية غير موثوقة.&lt;/p&gt;&lt;h3&gt;كيف أبدأ التداول من الصفر؟&lt;/h3&gt;&lt;p&gt;إذا كنت مبتدئًا ولا تمتلك خبرة سابقة في الأسواق المالية، فمن الأفضل أن تبدأ بخطوات تدريجية بدلًا من إيداع الأموال مباشرة في منصة لا تعرف عنها الكثير.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة الأولى: تعلم أساسيات التداول&lt;/h4&gt;&lt;p&gt;ابدأ بفهم المصطلحات الأساسية مثل سعر الشراء وسعر البيع وفارق السعر والعمولة والسيولة والتقلب والرافعة المالية والهامش وأوامر وقف الخسارة.&lt;/p&gt;&lt;p&gt;تعلم أيضًا الفرق بين الاستثمار في أصل مالي وشراء عقد مشتق يعتمد على سعر ذلك الأصل؛ فقد يبدو الاسمان متشابهين، لكن المخاطر والحقوق والتكاليف قد تختلف كثيرًا.&lt;/p&gt;&lt;p&gt;خصص وقتًا للتعلم من مصادر تعليمية موثوقة، مثل المواقع الرسمية للجهات الرقابية والبورصات والمواد التعليمية التي توضح آلية عمل الأسواق.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة الثانية: حدد السوق الذي تريد التداول فيه&lt;/h4&gt;&lt;p&gt;لا تحاول تعلم جميع الأسواق في وقت واحد. اختر سوقًا واحدًا في البداية، مثل الأسهم أو العملات الأجنبية، وتعرف إلى ساعات عمله والعوامل التي تؤثر في الأسعار والتكاليف المرتبطة بالتداول فيه.&lt;/p&gt;&lt;p&gt;إذا كنت تفضل تجنب الرافعة المالية والمشتقات المعقدة، فقد يكون البدء بدراسة الاستثمار في الأسهم أو الصناديق المتنوعة خيارًا تعليميًا أبسط من المضاربة السريعة، مع بقاء مخاطر انخفاض قيمة الاستثمار قائمة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة الثالثة: حدد هدفك المالي ومدى تحملك للمخاطر&lt;/h4&gt;&lt;p&gt;اسأل نفسك: هل تريد التعلم فقط؟ أم الاستثمار لسنوات؟ أم ممارسة التداول على المدى القصير؟&lt;/p&gt;&lt;p&gt;حدد كذلك مقدار المال الذي يمكنك تحمل خسارته دون التأثير في احتياجاتك الأساسية. لا تستخدم أموال الإيجار أو المصروفات اليومية أو الأموال المقترضة في المضاربة.&lt;/p&gt;&lt;p&gt;ولا تفترض أن امتلاك رأس مال كبير سيؤدي تلقائيًا إلى تحقيق أرباح أكبر؛ فقد يؤدي إلى خسائر أكبر أيضًا إذا لم تكن إدارة المخاطر جيدة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة الرابعة: اختر وسيطًا ماليًا مرخصًا&lt;/h4&gt;&lt;p&gt;يعد اختيار الوسيط من أهم خطوات البدء. ابحث عن شركة تتمتع بترخيص من جهة رقابية معروفة، وتأكد من أن الترخيص يشمل الخدمة التي تريد استخدامها وأن الشركة مسموح لها بتقديم خدماتها للمقيمين في بلدك.&lt;/p&gt;&lt;p&gt;لا تكتفِ بوجود شعار جهة رقابية على الموقع الإلكتروني. ادخل إلى سجل الجهة الرقابية بنفسك، وابحث عن الاسم القانوني للشركة ورقم الترخيص والموقع الإلكتروني وبيانات الاتصال.&lt;/p&gt;&lt;p&gt;تأكد أيضًا من أن الحساب الذي ستفتحه تابع للكيان القانوني المرخص نفسه، وليس لشركة أخرى تستخدم اسمًا مشابهًا.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة الخامسة: افتح حسابًا تجريبيًا&lt;/h4&gt;&lt;p&gt;تتيح العديد من شركات الوساطة حسابات تجريبية تستخدم أموالًا افتراضية لمحاكاة التداول في السوق.&lt;/p&gt;&lt;p&gt;يساعدك الحساب التجريبي على تجربة منصة التداول وفهم أنواع الأوامر وتدريب نفسك على تنفيذ الاستراتيجية دون المخاطرة بأموال حقيقية.&lt;/p&gt;&lt;p&gt;ومع ذلك، فإن النجاح في الحساب التجريبي لا يضمن تحقيق النتائج نفسها في الحساب الحقيقي، بسبب الاختلافات النفسية والتنفيذية وتكاليف التداول وظروف السوق.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة السادسة: تعلم إدارة رأس المال&lt;/h4&gt;&lt;p&gt;إدارة رأس المال هي مجموعة القواعد التي تساعدك على الحد من أثر الخسائر وحماية أموالك من الاستنزاف السريع.&lt;/p&gt;&lt;p&gt;يمكنك البدء بوضع حد أقصى للمبلغ الذي تخاطر به في الصفقة الواحدة، وتجنب تركيز كامل رأس المال في أصل واحد، والابتعاد عن مضاعفة حجم الصفقات بهدف تعويض الخسائر.&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا كان رأس مالك 1,000 دولار وقررت أن تكون المخاطرة المخططة في الصفقة 1%، فإن المبلغ المعرض للخطر وفق خطتك يساوي 10 دولارات. لكن هذا لا يضمن أن الخسارة الفعلية لن تتجاوز ذلك المبلغ، إذ قد تحدث فجوات سعرية أو انزلاقات في التنفيذ.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة السابعة: ابدأ بمبلغ صغير عند الاستعداد&lt;/h4&gt;&lt;p&gt;بعد اكتساب المعرفة والتدرب، يمكنك التفكير في بدء التداول الحقيقي بمبلغ صغير يتناسب مع وضعك المالي، إذا قررت أن التداول مناسب لك.&lt;/p&gt;&lt;p&gt;ابدأ بفهم جميع الرسوم وشروط السحب والإيداع، ولا تستخدم الرافعة المالية قبل استيعاب كيفية عملها ومخاطرها. كما لا تدخل الصفقات بناءً على توصيات مجهولة أو وعود بأرباح سريعة.&lt;/p&gt;&lt;p&gt;احتفظ بسجل لصفقاتك، وسجل أسباب الدخول والخروج والنتائج والأخطاء التي لاحظتها. سيساعدك ذلك على تقييم أسلوبك بصورة أكثر موضوعية.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة الثامنة: راجع نتائجك باستمرار&lt;/h4&gt;&lt;p&gt;لا تقيس نجاحك بصفقة واحدة أو يوم واحد. راجع نتائجك خلال فترة مناسبة، واهتم بحجم الخسائر مقارنة بالأرباح، ومدى التزامك بالخطة، وتأثير الرسوم، وعدد الصفقات غير المدروسة.&lt;/p&gt;&lt;p&gt;إذا وجدت أن التداول يسبب لك ضغطًا نفسيًا أو يدفعك إلى اتخاذ قرارات اندفاعية، فمن الأفضل التوقف مؤقتًا وإعادة تقييم خطتك.&lt;/p&gt;&lt;h3&gt;ما هي الأسواق الموثوقة للتداول؟&lt;/h3&gt;&lt;p&gt;من المهم توضيح أن السوق المالي نفسه يختلف عن الوسيط الذي يتيح لك الوصول إليه. فقد يكون السوق منظمًا، بينما تتعامل مع وسيط غير مرخص أو شركة تنتحل اسم جهة معروفة.&lt;/p&gt;&lt;p&gt;لذلك، لا توجد قائمة واحدة تجعل جميع الأصول أو المنصات آمنة بصورة مطلقة. والأفضل هو تقييم السوق والمنتج المالي والوسيط والجهة الرقابية كلًّا على حدة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;1. الأسواق المنظمة والبورصات الرسمية&lt;/h4&gt;&lt;p&gt;تعد البورصات المنظمة، مثل بورصة نيويورك وناسداك وبورصة لندن، أمثلة على أسواق مالية تعمل ضمن أطر تنظيمية وإفصاحية محددة.&lt;/p&gt;&lt;p&gt;يمكن أن تكون هذه الأسواق نقطة بداية جيدة للتعرف إلى تداول الأسهم، لكن وجود بورصة منظمة لا يلغي مخاطر الاستثمار أو احتمالية خسارة الأموال.&lt;/p&gt;&lt;p&gt;تحقق من أن الوصول إلى السوق يتم عبر وسيط مرخص، وأن المنتج الذي تشتريه مفهوم ومناسب لأهدافك.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;2. الوسطاء المرخصون من الجهات الرقابية&lt;/h4&gt;&lt;p&gt;بدلًا من الاعتماد على تقييمات مجهولة أو إعلانات المؤثرين، تحقق من تسجيل الوسيط لدى الجهة الرقابية المختصة.&lt;/p&gt;&lt;p&gt;من أمثلة الجهات الرقابية المعروفة:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;هيئة الأوراق المالية والبورصات الأمريكية (SEC):&lt;/strong&gt; تنظم جوانب مهمة من سوق الأوراق المالية في الولايات المتحدة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;هيئة تنظيم الصناعة المالية الأمريكية (FINRA):&lt;/strong&gt; توفر أدوات للتحقق من شركات الوساطة والأفراد المسجلين ضمن نطاق اختصاصها.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;هيئة السلوك المالي البريطانية (FCA):&lt;/strong&gt; تشرف على الأنشطة المالية التي تدخل ضمن اختصاصها في المملكة المتحدة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;هيئة الأوراق المالية والأسواق الأوروبية (ESMA):&lt;/strong&gt; تضطلع بمهام تنظيمية ورقابية على مستوى الاتحاد الأوروبي، إلى جانب السلطات الوطنية المختصة.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;strong&gt;هيئة الأوراق المالية والسلع في دولة الإمارات العربية المتحدة:&lt;/strong&gt; تعد من الجهات التنظيمية التي ينبغي الرجوع إلى سجلاتها الرسمية للتحقق من الجهات الواقعة ضمن اختصاصها، مع مراعاة التغييرات التنظيمية وأسماء الجهات الحالية.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;تختلف صلاحيات هذه الجهات ونطاق الحماية التي توفرها، لذلك يجب التحقق من الجهة المختصة في بلد إقامتك، ومن نوع الخدمة المالية التي يقدمها الوسيط.&lt;/p&gt;&lt;h3&gt;3. كيف تختار منصة تداول موثوقة؟&lt;/h3&gt;&lt;p&gt;قبل فتح الحساب، تحقق من مجموعة من المعايير الأساسية:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الترخيص القانوني:&lt;/strong&gt; ابحث عن الشركة في السجل الرسمي للجهة الرقابية، وتأكد من مطابقة الاسم القانوني ورقم الترخيص والموقع الإلكتروني.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;حماية أموال العملاء:&lt;/strong&gt; اقرأ شروط حفظ أموال العملاء، وما إذا كانت هناك ترتيبات للفصل بين أموال العملاء وأموال الشركة، وما هي حدود الحماية المتاحة في حالة تعثر الشركة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الرسوم والعمولات:&lt;/strong&gt; قارن فروق الأسعار وعمولات التداول ورسوم الإيداع والسحب ورسوم تحويل العملات وتكاليف التمويل أو التبييت.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;سهولة السحب:&lt;/strong&gt; اقرأ شروط سحب الأموال، وتحقق من إجراءات التحقق من الهوية والمدة المتوقعة والرسوم، ولا تعتمد على سهولة الإيداع وحدها لتقييم المنصة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الأمان الإلكتروني:&lt;/strong&gt; اختر منصة توفر وسائل حماية مناسبة للحساب، مثل المصادقة متعددة العوامل والتنبيهات الأمنية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;جودة خدمة العملاء:&lt;/strong&gt; تحقق من وجود بيانات اتصال رسمية وشروط واضحة لتقديم الشكاوى وتسوية النزاعات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الشفافية:&lt;/strong&gt; يجب أن توضح الشركة المنتجات المتاحة ومخاطرها ورسومها والجهة القانونية التي ستتعامل معها.&lt;/p&gt;&lt;h3&gt;كيف تتجنب شركات التداول النصابة؟&lt;/h3&gt;&lt;p&gt;ينبغي الانتباه إلى أن &lt;a href="https://www.nusurtech.ca/2026/08/most-common-scams-targeting-shamcash-users.html" target="_blank"&gt;الاحتيال المالي&lt;/a&gt; قد يتخذ أشكالًا متعددة، وقد تستخدم الشركات الوهمية مواقع احترافية وشعارات جهات رقابية حقيقية لإقناع العملاء.&lt;/p&gt;&lt;p&gt;من أبرز العلامات التحذيرية:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;الوعد بأرباح ثابتة أو مضمونة مهما كانت ظروف السوق.&lt;/li&gt;&lt;li&gt;الضغط عليك لإيداع الأموال بسرعة بحجة وجود فرصة لن تتكرر.&lt;/li&gt;&lt;li&gt;التواصل المتكرر من أشخاص يطلبون منك زيادة رأس المال لتعويض الخسائر.&lt;/li&gt;&lt;li&gt;طلب تحويل الأموال إلى حساب شخصي أو محفظة رقمية غير موثوقة.&lt;/li&gt;&lt;li&gt;تقديم رقم ترخيص لا يتطابق مع بيانات الشركة في السجل الرسمي.&lt;/li&gt;&lt;li&gt;فرض رسوم غير واضحة أو طلب مبالغ إضافية غير مبررة قبل السماح بالسحب.&lt;/li&gt;&lt;li&gt;الاعتماد على صور أرباح وشهادات مجهولة بدلًا من الإفصاحات والبيانات القابلة للتحقق.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ومن المهم أن تعرف أن ظهور الشركة في إعلان على مواقع التواصل الاجتماعي، أو امتلاكها عددًا كبيرًا من المتابعين، أو حصولها على تقييمات إيجابية، لا يثبت أنها مرخصة أو موثوقة.&lt;/p&gt;&lt;p&gt;إذا شككت في منصة ما، فتوقف عن تحويل الأموال إليها، وتواصل مع الجهة الرقابية أو المؤسسة المالية المعنية عبر قنواتها الرسمية.&lt;/p&gt;&lt;h3&gt;ما المبلغ المناسب للبدء في التداول؟&lt;/h3&gt;&lt;p&gt;لا يوجد مبلغ واحد مناسب للجميع، لأن الحد الأدنى يختلف من وسيط إلى آخر ومن سوق إلى آخر. كما يعتمد المبلغ المناسب على وضعك المالي وأهدافك ومدى تحملك للمخاطر.&lt;/p&gt;&lt;p&gt;قبل إيداع أي أموال، احرص على تكوين احتياطي للطوارئ، وتسديد الالتزامات ذات الأولوية، وعدم استخدام أموال تحتاج إليها في المستقبل القريب.&lt;/p&gt;&lt;p&gt;إذا كان هدفك تعلم التداول، فقد يكون الحساب التجريبي كافيًا في المرحلة الأولى. وإذا قررت الانتقال إلى الحساب الحقيقي، فابدأ بمبلغ يمكنك تحمل خسارته بالكامل دون أن يؤثر في حياتك الأساسية.&lt;/p&gt;&lt;p&gt;تذكر أن صغر المبلغ لا يجعل التداول خاليًا من المخاطر، وأن استخدام الرافعة المالية قد يزيد حجم التعرض للسوق مقارنة برأس المال المودع.&lt;/p&gt;&lt;h3&gt;هل التداول مناسب للمبتدئين؟&lt;/h3&gt;&lt;p&gt;يمكن للمبتدئين تعلم أساسيات التداول، لكن ذلك لا يعني أن التداول مناسب للجميع. فالنتائج تعتمد على عوامل متعددة، منها الخبرة والاستراتيجية والرسوم وظروف السوق والانضباط في إدارة المخاطر.&lt;/p&gt;&lt;p&gt;إذا كنت لا تملك الوقت الكافي لمتابعة الأسواق، أو لا تتحمل تقلب قيمة أموالك، فقد يكون الاستثمار طويل الأجل المتنوع، بعد دراسة احتياجاتك وأهدافك، أكثر ملاءمة من المضاربة اليومية.&lt;/p&gt;&lt;p&gt;أما إذا كنت مهتمًا بالتداول، فابدأ بالتعلم والتجربة دون مخاطرة، ولا تنتقل إلى التداول الحقيقي إلا بعد فهم طبيعة السوق والأداة المالية التي ستستخدمها.&lt;/p&gt;&lt;p&gt;ولا تجعل قرارك مبنيًا على قصص النجاح وحدها؛ فمن المهم إدراك أن بعض المتداولين يتكبدون خسائر كبيرة، وأن النتائج السابقة لا تضمن الأرباح المستقبلية.&lt;/p&gt;&lt;p&gt;التداول هو عملية شراء وبيع الأصول المالية بهدف الاستفادة من تغير الأسعار، ويمكن أن يشمل الأسهم والفوركس والذهب والسلع والمؤشرات والعملات المشفرة. لكن لكل سوق خصائصه ومخاطره، ولا توجد طريقة تضمن تحقيق الأرباح.&lt;/p&gt;&lt;p&gt;إذا كنت تتساءل عن كيفية البدء في التداول من الصفر، فإن الطريق الأفضل يبدأ بتعلم الأساسيات، واختيار سوق واحد لفهمه، والتدرب على حساب تجريبي، ووضع خطة واضحة لإدارة المخاطر، ثم التحقق من ترخيص الوسيط قبل إيداع أي أموال.&lt;/p&gt;&lt;p&gt;أما بالنسبة إلى الأسواق الموثوقة، فالأولوية تكون للأسواق المنظمة والوسطاء المرخصين الذين يمكن التحقق من بياناتهم عبر السجلات الرسمية، مع الانتباه إلى أن الترخيص لا يمنع خسائر الاستثمار ولا يجعل كل المنتجات المالية مناسبة للجميع.&lt;/p&gt;&lt;p&gt;وأخيرًا، تذكر أن النجاح في الأسواق المالية لا يعتمد على الحظ وحده أو على توقع حركة السعر بصورة صحيحة في كل مرة، بل يتطلب المعرفة والصبر والانضباط والقدرة على التعامل مع الخسائر دون اتخاذ قرارات متهورة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تنبيه:&lt;/strong&gt; هذا المقال لأغراض التوعية والتعليم فقط، ولا يمثل توصية بشراء أو بيع أي أصل مالي. التداول ينطوي على مخاطر، وقد يؤدي إلى خسارة جزء من رأس المال أو كله، بحسب الأداة المالية وظروف السوق.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;روابط رسمية موثوقة للتداول&lt;/h3&gt;&lt;p&gt;&lt;a href="https://www.esma.europa.eu/investor-corner/is-the-firm-regulated?" target="_blank"&gt;التحقق من شركات الاستثمار المرخصة في الاتحاد الأوروبي – ESMA&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://brokercheck.finra.org/" target="_blank"&gt;البحث عن الوسطاء وشركات الوساطة – FINRA BrokerCheck&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.fca.org.uk/consumers/how-check-firm-individual-authorised" target="_blank"&gt;التحقق من ترخيص الشركات المالية في بريطانيا – FCA&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.fca.org.uk/consumers/online-trading-scams" target="_blank"&gt;التحذير من عمليات الاحتيال في التداول الإلكتروني – FCA&lt;/a&gt;&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/7095126041674796494/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/what-is-trading.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/7095126041674796494" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/7095126041674796494" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/what-is-trading.html" rel="alternate" title="ماهو التداول Trading وكيف ابدأ التداول وماهي الاسواق الموثوقة" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWB_XzegMRjoKBXSCrVr6G_PSrMk5aR32lYH1CtMqV2MifaKaL1aMiPkMNQ0krsE_cHa5M6FQ9G4MWHQcdrshhd4EL_zE8Q9-hXqLfobyypPBoQnirBxaZnTB6eRKGAQntuUQhIacS_Rn8WYRlGenc-dNyLq0s2G7akXImByps1VNfnWxTlMlCJVVP41Qq/s72-c/imageedit_1_9272739681.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-6387649506126468715</id><published>2026-10-16T12:31:33.830+03:00</published><updated>2026-10-16T12:31:33.830+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">جوجل ويونيتي تطلقان Playground لإنشاء ألعاب الفيديو بالذكاء الاصطناعي</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi040v2EOGgR8cQlRCb-Z_YYaif-j5jnkS92bUjL_uEYIRnU4oCLs0a0cJP7GdqyBNmLpXftviHQL0dsQGfRXy_fUMWBjhmKn7Dr5UFoeVa_ThSC5UKpOIyBSrURkyoyPoycks8d5ehvbP-olncnSCMzCFhOabY_i7XzHv0vqjXX5RZsFNZ5wRuC11-uMKO/s640/imageedit_2_6296520505.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="جوجل ويونيتي تطلقان Playground لإنشاء ألعاب الفيديو بالذكاء الاصطناعي بمجرد كتابة الأوامر النصية" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi040v2EOGgR8cQlRCb-Z_YYaif-j5jnkS92bUjL_uEYIRnU4oCLs0a0cJP7GdqyBNmLpXftviHQL0dsQGfRXy_fUMWBjhmKn7Dr5UFoeVa_ThSC5UKpOIyBSrURkyoyPoycks8d5ehvbP-olncnSCMzCFhOabY_i7XzHv0vqjXX5RZsFNZ5wRuC11-uMKO/s1600/imageedit_2_6296520505.webp" title="جوجل ويونيتي تطلقان Playground لإنشاء ألعاب الفيديو بالذكاء الاصطناعي بمجرد كتابة الأوامر النصية" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;جوجل ويونيتي تطلقان Playground لإنشاء ألعاب الفيديو&lt;/h3&gt;&lt;p&gt;يشهد قطاع تطوير ألعاب الفيديو تحولًا كبيرًا بفضل التطورات المتسارعة في تقنيات الذكاء الاصطناعي، التي أصبحت تتيح للمطورين والمصممين إنشاء أفكار وتجارب تفاعلية بطرق كانت تتطلب في السابق ساعات طويلة من البرمجة والتصميم والاختبار. وفي ظل هذا التحول، يبرز التعاون بين شركات التكنولوجيا الكبرى ومنصات تطوير الألعاب بوصفه خطوة مهمة نحو جعل صناعة الألعاب أكثر سهولة ومرونة، مع فتح المجال أمام المبتدئين والمبدعين المستقلين لتجربة أفكارهم دون الحاجة إلى امتلاك خبرة تقنية متقدمة.&lt;/p&gt;&lt;p&gt;وفي هذا السياق، يسلط عنوان إطلاق &lt;strong&gt;Playground بالتعاون بين جوجل ويونيتي لإنشاء ألعاب الفيديو بالذكاء الاصطناعي بمجرد كتابة الأوامر النصية&lt;/strong&gt; الضوء على توجه جديد في عالم تطوير الألعاب، يقوم على تحويل الأوصاف المكتوبة باللغة الطبيعية إلى تجارب يمكن استكشافها والتفاعل معها. ويعكس هذا التوجه الاهتمام المتزايد باستخدام الذكاء الاصطناعي لتقليل الحواجز أمام تطوير الألعاب، وتسريع بناء النماذج الأولية، ومساعدة المطورين على الانتقال من مرحلة الفكرة إلى مرحلة التجربة العملية في وقت أقصر.&lt;/p&gt;&lt;p&gt;لكن لفهم أهمية هذه الفكرة، ينبغي النظر إلى طبيعة الأدوات المستخدمة في صناعة الألعاب، والدور الذي تؤديه محركات التطوير مثل Unity، والإمكانات التي تقدمها تقنيات جوجل للذكاء الاصطناعي، إلى جانب التحديات التي قد تواجه هذه الأدوات عند الانتقال من إنشاء نماذج تجريبية بسيطة إلى إنتاج ألعاب متكاملة قابلة للنشر تجاريًا.&lt;/p&gt;&lt;h3&gt;ما هو Playground وكيف ترتبط فكرته بتطوير الألعاب بالذكاء الاصطناعي؟&lt;/h3&gt;&lt;p&gt;يشير مفهوم Playground في مجال الذكاء الاصطناعي عادةً إلى بيئة تجريبية تتيح للمستخدمين اختبار الأفكار والتفاعل مع النماذج التقنية بطريقة مباشرة، دون الحاجة إلى إعداد مشروع برمجي كامل منذ البداية. وفي مجال ألعاب الفيديو، يمكن أن تتحول هذه الفكرة إلى مساحة تسمح للمستخدم بوصف اللعبة التي يريدها، ثم مشاهدة نموذج تفاعلي يعكس بعض العناصر الأساسية التي حددها في وصفه.&lt;/p&gt;&lt;p&gt;على سبيل المثال، يمكن للمستخدم كتابة أمر نصي يطلب فيه إنشاء لعبة منصات ثنائية الأبعاد، يتحكم فيها اللاعب بشخصية تقفز بين المنصات وتتجنب العقبات وتجمع العملات للوصول إلى خط النهاية. وبدلًا من البدء بإنشاء المشاهد والشخصيات وإعداد قواعد الحركة يدويًا، يمكن لأداة مدعومة بالذكاء الاصطناعي أن تساعد في تحويل هذا الوصف إلى نموذج أولي قابل للتجربة، بحسب الإمكانات التي توفرها المنصة.&lt;/p&gt;&lt;p&gt;وقد يتضمن هذا النموذج عناصر مثل بيئة اللعب، والشخصية الرئيسية، والعقبات، وقواعد الفوز والخسارة، وبعض المؤثرات البصرية أو التفاعلات الأساسية. وبعد ذلك، يستطيع المستخدم تعديل وصفه وإضافة تفاصيل جديدة، مثل زيادة سرعة الشخصية، أو تغيير شكل البيئة، أو إضافة أعداء جدد، أو جعل مستوى الصعوبة يرتفع تدريجيًا.&lt;/p&gt;&lt;p&gt;ومع ذلك، من المهم التمييز بين الفكرة العامة لإنشاء الألعاب بالأوامر النصية وبين الميزات المحددة لأي منتج يحمل اسم Playground. فاسم Playground يُستخدم في أكثر من مشروع تقني، ولا يكفي وحده لإثبات أن أداة معينة أُطلقت رسميًا من جوجل ويونيتي أو أنها توفر جميع الوظائف المذكورة. لذلك، ينبغي الرجوع إلى الإعلان الرسمي الخاص بالمنتج لتأكيد تفاصيل الإطلاق، ومدى توفر الخدمة، والميزات المدعومة فعليًا.&lt;/p&gt;&lt;h3&gt;كيف يمكن للذكاء الاصطناعي تحويل الأوامر النصية إلى لعبة فيديو؟&lt;/h3&gt;&lt;p&gt;تعتمد فكرة إنشاء الألعاب باستخدام الأوامر النصية على قدرة نماذج الذكاء الاصطناعي على فهم اللغة الطبيعية وتحويلها إلى تعليمات أو مكونات يمكن للأنظمة البرمجية التعامل معها. ويبدأ المستخدم بكتابة وصف يحدد نوع اللعبة، وطبيعة الشخصيات، والبيئة المحيطة، والهدف المطلوب تحقيقه، ثم تتولى الأدوات المتاحة تفسير هذا الوصف والمساعدة في إنشاء العناصر المناسبة.&lt;/p&gt;&lt;p&gt;وتختلف آلية التنفيذ بحسب النظام المستخدم. فقد يعتمد الحل على نموذج لغوي لتفسير التعليمات، وأدوات لتوليد الأكواد البرمجية، وأنظمة لإنشاء الصور أو الأصول الفنية، إلى جانب محرك ألعاب يتولى تشغيل المشاهد ومعالجة الحركة والتصادمات والتفاعلات.&lt;/p&gt;&lt;p&gt;ولتبسيط الصورة، يمكن تقسيم العملية إلى عدة مراحل مترابطة:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;كتابة وصف اللعبة:&lt;/strong&gt; يحدد المستخدم الفكرة الرئيسية، مثل إنشاء لعبة سباق سيارات في مدينة مستقبلية أو لعبة مغامرات داخل غابة مليئة بالألغاز.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تحليل التعليمات:&lt;/strong&gt; يحاول النظام تحديد العناصر الأساسية المطلوبة، بما في ذلك الشخصيات، وقواعد الحركة، والأهداف، والعقبات، وطريقة تفاعل اللاعب مع البيئة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;إنشاء النموذج الأولي:&lt;/strong&gt; تُستخدم الإمكانات البرمجية المتاحة لإنشاء مشهد أو مجموعة من المكونات التي تمثل الفكرة الأولية للعبة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;تشغيل التجربة:&lt;/strong&gt; يتمكن المستخدم من اختبار النموذج ومعرفة ما إذا كانت الحركة والتفاعلات الأساسية تعمل بالطريقة المطلوبة.&lt;/li&gt;&lt;li&gt;&lt;strong&gt;التعديل والتحسين:&lt;/strong&gt; يكتب المستخدم أوامر إضافية لتغيير العناصر أو إصلاح بعض السلوكيات أو تجربة أفكار جديدة.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;وتكمن أهمية هذا الأسلوب في أنه يقلل الحاجة إلى تنفيذ كل خطوة يدويًا منذ البداية. لكنه لا يعني بالضرورة أن كل وصف نصي سيؤدي إلى لعبة مكتملة وخالية من الأخطاء؛ إذ تعتمد جودة النتيجة على دقة التعليمات، وقدرات النموذج، والأدوات المتكاملة معه، ومدى تعقيد اللعبة المطلوبة.&lt;/p&gt;&lt;h3&gt;دور جوجل في تطوير أدوات إنشاء الألعاب بالذكاء الاصطناعي&lt;/h3&gt;&lt;p&gt;تستثمر جوجل في تقنيات الذكاء الاصطناعي التوليدي التي يمكن توظيفها في مجموعة واسعة من المجالات، من بينها البرمجة، وإنشاء المحتوى، وتحليل الصور، وفهم التعليمات المكتوبة. ويمكن لهذه التقنيات أن تؤدي دورًا مهمًا في تبسيط عمليات تطوير الألعاب، خصوصًا عندما يجري دمجها مع أدوات قادرة على تحويل المخرجات النصية إلى عناصر قابلة للتنفيذ.&lt;/p&gt;&lt;p&gt;فعندما يصف المستخدم لعبة يريد إنشاءها، يمكن لنموذج ذكاء اصطناعي أن يساعد في تفكيك الفكرة إلى مهام أصغر، مثل إعداد حركة الشخصية، وإنشاء قواعد جمع العناصر، وتحديد سلوك الأعداء، وبناء نظام بسيط لحساب النقاط. كما يمكن للذكاء الاصطناعي المساعدة في اقتراح أفكار للمراحل أو كتابة أجزاء من الشيفرة البرمجية أو توليد أوصاف للأصول الفنية.&lt;/p&gt;&lt;p&gt;وتزداد أهمية هذه الإمكانات عندما يحتاج المطور إلى تجربة مجموعة كبيرة من الأفكار خلال وقت محدود. فبدلًا من قضاء وقت طويل في بناء نموذج أولي لكل فكرة، يمكنه الاستفادة من أدوات التوليد لتجهيز نسخة أولية ثم اختبارها وتعديلها بناءً على النتائج.&lt;/p&gt;&lt;p&gt;لكن ينبغي عدم افتراض أن كل أداة مرتبطة بجوجل تستخدم النموذج نفسه أو توفر جميع هذه الإمكانات بصورة مباشرة. فالتقنيات المتاحة تختلف من منتج إلى آخر، كما أن بعض الوظائف قد تكون تجريبية أو محدودة أو متاحة لفئات معينة من المستخدمين.&lt;/p&gt;&lt;h3&gt;لماذا تُعد Unity عنصرًا مهمًا في هذه المعادلة؟&lt;/h3&gt;&lt;p&gt;تُعد Unity من محركات تطوير الألعاب المعروفة، إذ توفر بيئة عمل لبناء تجارب تفاعلية ثنائية وثلاثية الأبعاد، مع أدوات للتعامل مع الرسوميات والحركة والإضاءة والتصادمات والصوت وواجهات المستخدم. كما تتيح للمطورين تنظيم المشاهد والشخصيات والمكونات البرمجية داخل مشروع واحد، ثم إعداد اللعبة لمنصات تشغيل مختلفة وفق متطلبات المشروع.&lt;/p&gt;&lt;p&gt;وتبرز قيمة محرك مثل Unity عند دمجه مع تقنيات الذكاء الاصطناعي، لأن توليد وصف أو صورة أو جزء من الشيفرة لا يكفي وحده لتشغيل لعبة متكاملة. فهناك حاجة إلى بيئة تجمع العناصر المختلفة وتدير تفاعلها، وتسمح للمطور بفحص النتائج وتعديلها واختبارها.&lt;/p&gt;&lt;p&gt;ومن الناحية العملية، يمكن أن يساعد الذكاء الاصطناعي في تسريع إنشاء بعض مكونات المشروع، بينما تتولى بيئة التطوير إدارة هذه المكونات ضمن بنية منظمة. وقد يشمل ذلك إنشاء شخصية قابلة للتحكم، أو تجهيز مشهد أولي، أو المساعدة في كتابة سكربتات للحركة والتصادمات، بحسب التكامل المتاح بين الأدوات.&lt;/p&gt;&lt;p&gt;كما يمكن لهذا النوع من التكامل أن يختصر الوقت الذي يحتاج إليه المطور لاختبار فكرة جديدة. فعلى سبيل المثال، إذا أراد مصمم لعبة تجربة آلية جديدة للقفز أو نظام مختلف لجمع النقاط، فقد تساعده الأدوات الذكية في إعداد نموذج تجريبي بدلًا من بناء كل العناصر يدويًا من الصفر.&lt;/p&gt;&lt;p&gt;ومع ذلك، فإن تحديد طبيعة التعاون بين جوجل ويونيتي في منتج Playground بعينه يتطلب الرجوع إلى المعلومات الرسمية، لأن العلاقة بين الشركتين قد تختلف بحسب المشروع، ولا ينبغي اعتبار الإمكانات العامة لمحرك Unity دليلًا على وجود ميزة محددة داخل المنتج المذكور.&lt;/p&gt;&lt;h3&gt;إنشاء الألعاب دون خبرة برمجية متقدمة&lt;/h3&gt;&lt;p&gt;من أبرز الوعود التي يقدمها الذكاء الاصطناعي في مجال تطوير الألعاب تقليل الحواجز التقنية أمام الأشخاص الذين يمتلكون أفكارًا إبداعية لكنهم لا يعرفون كيفية تحويلها إلى برامج قابلة للتشغيل.&lt;/p&gt;&lt;p&gt;ففي الماضي، كان إنشاء لعبة بسيطة يتطلب غالبًا تعلم أساسيات البرمجة، والتعامل مع محرك ألعاب، وفهم كيفية تحريك الشخصيات، وإدارة التصادمات، وتصميم المراحل، وربط الأحداث المختلفة بعضها ببعض. وحتى المشروعات الصغيرة كانت تحتاج إلى قدر من المعرفة التقنية والوقت للتجربة وتصحيح الأخطاء.&lt;/p&gt;&lt;p&gt;أما في بيئة تعتمد على الأوامر النصية، فيمكن للمستخدم البدء بوصف ما يريد بلغة بسيطة، ثم تطوير الفكرة تدريجيًا. ويمكنه مثلًا كتابة تعليمات من قبيل: «أنشئ لعبة ثنائية الأبعاد يتحرك فيها اللاعب يمينًا ويسارًا، ويقفز فوق الحواجز، ويحصل على نقاط عند جمع النجوم».&lt;/p&gt;&lt;p&gt;وبعد تجربة النموذج، يمكنه إضافة تعليمات أخرى مثل جعل العقبات أسرع مع تقدم المستوى، أو تغيير الخلفية إلى بيئة فضائية، أو إضافة مؤثر صوتي عند جمع النجوم، أو إنشاء شاشة تعرض النتيجة النهائية.&lt;/p&gt;&lt;p&gt;وتتيح هذه الطريقة للمبتدئين التركيز على تصميم التجربة وقواعد اللعب بدلًا من الانشغال بجميع التفاصيل البرمجية منذ اللحظة الأولى. كما تمنح المعلمين والطلاب وسيلة عملية لفهم مبادئ تصميم الألعاب، من خلال تجربة الأفكار وملاحظة نتائجها بصورة مباشرة.&lt;/p&gt;&lt;p&gt;لكن عبارة «دون خبرة برمجية» لا تعني أن الخبرة التقنية أصبحت بلا قيمة. فكلما زادت تعقيدات المشروع، ازدادت الحاجة إلى فهم طريقة عمل المحرك، ومراجعة الأكواد، واكتشاف الأخطاء، والتأكد من أن اللعبة تعمل بصورة مستقرة على الأجهزة المستهدفة.&lt;/p&gt;&lt;h3&gt;ما أنواع الألعاب التي يمكن إنشاؤها باستخدام الأوامر النصية؟&lt;/h3&gt;&lt;p&gt;تتوقف أنواع الألعاب التي يمكن إنشاؤها باستخدام الذكاء الاصطناعي على قدرات المنصة المستخدمة، ومدى تكاملها مع محرك الألعاب، والأدوات المتاحة لتوليد الرسومات والبرمجة. ومع ذلك، توجد مجموعة من الأنواع التي يمكن أن تستفيد بصورة واضحة من هذا الأسلوب، خصوصًا عند إنشاء النماذج الأولية والتجارب البسيطة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;1. ألعاب المنصات ثنائية الأبعاد&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تُعد ألعاب المنصات من الخيارات المناسبة لتجربة إنشاء الألعاب بالأوامر النصية، نظرًا إلى اعتمادها على قواعد واضحة نسبيًا، مثل حركة الشخصية والقفز والتصادم مع المنصات وجمع العناصر. ويمكن للمستخدم البدء بمرحلة صغيرة، ثم إضافة العقبات والأعداء والمكافآت تدريجيًا.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2. ألعاب الألغاز والتفكير&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكن للذكاء الاصطناعي المساعدة في إنشاء ألعاب تعتمد على حل الألغاز أو ترتيب العناصر أو اكتشاف الأنماط. كما يمكن للمستخدم تجربة مستويات مختلفة من الصعوبة، وتعديل القواعد للوصول إلى تجربة أكثر تنوعًا.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3. ألعاب السباقات&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تتيح النماذج الأولية لألعاب السباقات اختبار عناصر مثل حركة السيارة، وطريقة التحكم، والمسار، والعقبات. وقد تساعد الأوامر النصية في تعديل سرعة المركبات أو تصميم مسار جديد أو تجربة آليات مختلفة للتحكم.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;4. ألعاب المغامرات والاستكشاف&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكن وصف عالم افتراضي يحتوي على شخصيات وأماكن وأهداف محددة، ثم استخدام الأدوات المتاحة لإنشاء نموذج أولي يوضح طريقة استكشاف البيئة والتفاعل مع عناصرها. وتزداد أهمية المراجعة البشرية في هذا النوع من الألعاب عندما تتعدد المهام وتتفرع القصة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;5. الألعاب التعليمية&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكن للمعلمين الاستفادة من هذه التقنيات لإنشاء نماذج لألعاب تعليمية تساعد الطلاب على تعلم الرياضيات أو اللغات أو العلوم. فعلى سبيل المثال، يمكن تصميم تجربة بسيطة يحصل فيها اللاعب على نقاط عند الإجابة الصحيحة، مع إضافة مستويات تتدرج في الصعوبة.&lt;/p&gt;&lt;p&gt;وتظل هذه الأمثلة توضيحًا للاستخدامات المحتملة لتقنيات إنشاء الألعاب بالذكاء الاصطناعي، وليست تأكيدًا على أن جميع هذه الأنواع مدعومة مباشرة في Playground المقصود.&lt;/p&gt;&lt;h3&gt;كيف يمكن أن يستفيد مطورو الألعاب من Playground؟&lt;/h3&gt;&lt;p&gt;لا تقتصر أهمية أدوات الذكاء الاصطناعي على المبتدئين، بل يمكن أن يستفيد منها المطورون المحترفون أيضًا، خاصة في المراحل المبكرة من الإنتاج، عندما يحتاج فريق العمل إلى اختبار عدد كبير من الأفكار قبل اختيار التصميم النهائي.&lt;/p&gt;&lt;p&gt;ففي صناعة الألعاب، قد يستغرق اختبار فكرة جديدة وقتًا طويلًا إذا كان يتطلب إنشاء مشهد كامل وإعداد الشخصيات وكتابة الأكواد اللازمة لتشغيله. ويمكن لأدوات التوليد الذكي أن تساعد في اختصار بعض هذه الخطوات، من خلال تجهيز عناصر أولية أو اقتراح حلول برمجية أو تسريع عمليات التعديل المتكررة.&lt;/p&gt;&lt;p&gt;كما يمكن استخدامها لاستكشاف أساليب مختلفة لتصميم المراحل، وتجربة آليات اللعب، ومقارنة أكثر من تصور قبل الاستثمار في تطويره بصورة كاملة.&lt;/p&gt;&lt;p&gt;وتظهر فائدة أخرى في التواصل بين أعضاء الفريق. فقد يتمكن مصمم اللعبة من شرح فكرته باستخدام وصف نصي واضح، ثم الاستفادة من نموذج أولي لتوضيحها للمبرمجين والفنانين. ويساعد ذلك على تقليل الفجوة بين التصور الإبداعي والتنفيذ التقني.&lt;/p&gt;&lt;p&gt;ومع ذلك، لا يُفترض أن تحل هذه الأدوات محل الاختبارات الاحترافية أو أنظمة إدارة المشاريع أو مراجعة الشيفرة البرمجية. بل إن الاستخدام الأكثر فاعلية لها يكون عادةً ضمن سير عمل يجمع بين الأتمتة والخبرة البشرية، بحيث يتولى الذكاء الاصطناعي تسريع المهام المناسبة، بينما يراجع المطورون النتائج ويتأكدون من جودتها.&lt;/p&gt;&lt;h3&gt;هل يمكن إنشاء لعبة كاملة جاهزة للنشر بمجرد كتابة وصف؟&lt;/h3&gt;&lt;p&gt;رغم التطور الملحوظ في الذكاء الاصطناعي التوليدي، فإن الانتقال من فكرة مكتوبة إلى لعبة تجارية مكتملة لا يزال يتطلب أكثر من مجرد إنشاء نموذج أولي.&lt;/p&gt;&lt;p&gt;فاللعبة الاحترافية تحتاج إلى أنظمة مترابطة تشمل منطق اللعب، والرسومات، والصوت، وواجهات المستخدم، وحفظ التقدم، وإدارة الأداء، واختبار التوافق مع الأجهزة المختلفة. وقد تتطلب أيضًا أنظمة للشبكات واللعب الجماعي، أو إدارة الحسابات، أو حماية بيانات المستخدمين، وفق طبيعة المشروع.&lt;/p&gt;&lt;p&gt;وحتى إذا نجح الذكاء الاصطناعي في إنشاء جزء كبير من هذه العناصر، فإن المخرجات قد تتضمن أخطاء برمجية أو سلوكيات غير متوقعة أو تفاصيل لا تتطابق تمامًا مع وصف المستخدم.&lt;/p&gt;&lt;p&gt;ومن التحديات كذلك الحفاظ على اتساق التصميم. فقد يؤدي تعديل عنصر واحد إلى التأثير في أجزاء أخرى من اللعبة، مثل تغيير سرعة الشخصية بطريقة تجعل بعض العقبات مستحيلة، أو إضافة آلية جديدة تتعارض مع قواعد الفوز والخسارة.&lt;/p&gt;&lt;p&gt;ولهذا السبب، ينبغي النظر إلى إنشاء الألعاب بالأوامر النصية باعتباره وسيلة لتسريع التطوير وتسهيل التجربة، لا ضمانًا لإنتاج لعبة نهائية مثالية دون تدخل بشري.&lt;/p&gt;&lt;p&gt;أما إذا كانت المنصة توفر أدوات متقدمة للتحرير والاختبار والتصدير، فقد يصبح الانتقال إلى مراحل الإنتاج أكثر سهولة، لكن ذلك يظل مرتبطًا بالميزات الفعلية المتاحة وشروط استخدامها.&lt;/p&gt;&lt;h3&gt;التحديات والقيود التي تواجه تطوير الألعاب بالذكاء الاصطناعي&lt;/h3&gt;&lt;p&gt;على الرغم من الفرص الكبيرة التي يوفرها هذا المجال، فإن هناك عددًا من التحديات التي يجب أخذها في الاعتبار عند تقييم أي منصة لإنشاء ألعاب الفيديو باستخدام النصوص.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;جودة النتائج:&lt;/strong&gt; قد يفسر النظام بعض التعليمات بطريقة مختلفة عن قصد المستخدم، خصوصًا عندما يكون الوصف غامضًا أو يتضمن قواعد متعارضة. ولذلك تساعد الأوامر المحددة والمقسمة إلى خطوات صغيرة على تحسين النتائج.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;التحكم في التفاصيل:&lt;/strong&gt; قد يكون من السهل طلب تغيير لون الخلفية أو سرعة الشخصية، لكن التحكم الدقيق في أنظمة معقدة أو سلوكيات متداخلة قد يحتاج إلى تعديلات يدوية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الأداء والتوافق:&lt;/strong&gt; لا يعني نجاح اللعبة داخل بيئة تجريبية أنها ستعمل بالسرعة نفسها على الهواتف والأجهزة الضعيفة وأجهزة الحاسوب المختلفة. فالأداء يحتاج إلى اختبار وتحسين مستقلين.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الحقوق والملكية الفكرية:&lt;/strong&gt; يجب على المستخدمين مراجعة شروط الخدمة والتراخيص المتعلقة بالأصول الفنية والأكواد والمحتوى الذي تنتجه الأدوات الذكية، خصوصًا عند استخدامه في ألعاب تجارية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخصوصية والأمان:&lt;/strong&gt; ينبغي تجنب إدخال معلومات حساسة أو شيفرات سرية في أدوات لا تسمح سياساتها بذلك، مع ضرورة مراجعة الأكواد التي يتم توليدها قبل استخدامها في تطبيقات متصلة بالإنترنت أو تتعامل مع بيانات المستخدمين.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;التكلفة وحدود الاستخدام:&lt;/strong&gt; قد تفرض بعض المنصات قيودًا على عدد الطلبات أو سرعة التوليد أو الوصول إلى الميزات المتقدمة، وقد تختلف شروط الاستخدام بين الحسابات المجانية والمدفوعة.&lt;/p&gt;&lt;p&gt;وتوضح هذه التحديات أن نجاح أي أداة لإنشاء الألعاب لا يعتمد فقط على قدرتها على توليد محتوى جذاب، بل يتطلب أيضًا توفير بيئة مستقرة وآمنة تسمح للمستخدم بتطوير مشروعه واختباره وتحسينه.&lt;/p&gt;&lt;h3&gt;كيف ينعكس هذا التطور على مستقبل صناعة ألعاب الفيديو؟&lt;/h3&gt;&lt;p&gt;قد يسهم انتشار أدوات إنشاء الألعاب بالذكاء الاصطناعي في تغيير طريقة عمل فرق التطوير، إذ يصبح اختبار الأفكار أكثر سرعة، ويستطيع عدد أكبر من الأشخاص المشاركة في مراحل التصميم والتجربة.&lt;/p&gt;&lt;p&gt;ومن المحتمل أن تظهر فرص جديدة أمام المطورين المستقلين وصناع المحتوى والمعلمين والطلاب، خاصة لمن لا يمتلكون الموارد اللازمة لبناء فرق متخصصة في البرمجة والفن والصوت. وقد تساعد الأدوات الذكية على تقليل تكلفة بعض مراحل الإنتاج الأولية، وتمنح المبدعين فرصة أكبر لاختبار أفكار غير تقليدية.&lt;/p&gt;&lt;p&gt;كذلك يمكن أن يصبح التفاعل مع محركات الألعاب أكثر اعتمادًا على اللغة الطبيعية. فبدلًا من التنقل بين عدد كبير من القوائم والإعدادات لتنفيذ تعديل معين، قد يتمكن المطور من وصف النتيجة المطلوبة، ثم مراجعة التغييرات التي يقترحها النظام واعتمادها أو تعديلها.&lt;/p&gt;&lt;p&gt;لكن هذا التطور لن يلغي الحاجة إلى المصممين والمبرمجين بالضرورة. فالألعاب المميزة لا تعتمد على التكنولوجيا وحدها، بل على جودة الفكرة، وتوازن آليات اللعب، وتصميم المستويات، والسرد، وفهم سلوك اللاعبين. وسيظل الإبداع البشري مهمًا في تحديد ما يجعل اللعبة ممتعة ومختلفة وقادرة على جذب الجمهور.&lt;/p&gt;&lt;p&gt;ومن المتوقع أيضًا أن يزداد التركيز على المهارات التي تساعد المطورين على توجيه أدوات الذكاء الاصطناعي ومراجعة مخرجاتها، مثل صياغة التعليمات بدقة، وتحليل الأخطاء، واختبار التجارب، وتحسين الأداء.&lt;/p&gt;&lt;h3&gt;هل تمثل Playground خطوة جديدة نحو ديمقراطية تطوير الألعاب؟&lt;/h3&gt;&lt;p&gt;تعكس فكرة إنشاء ألعاب الفيديو بالذكاء الاصطناعي بمجرد كتابة الأوامر النصية اتجاهًا مهمًا في تطور أدوات البرمجة والإبداع الرقمي. فهي تسعى إلى جعل عملية تطوير الألعاب أكثر سهولة، وتقليل الوقت اللازم لبناء النماذج الأولية، ومنح المستخدمين فرصة لتحويل أفكارهم إلى تجارب قابلة للاختبار دون الحاجة إلى البدء من الصفر.&lt;/p&gt;&lt;p&gt;ويمكن أن يكون الجمع بين قدرات الذكاء الاصطناعي وأدوات تطوير الألعاب مثل Unity مفيدًا للمبتدئين والمحترفين على حد سواء، سواء في إنشاء ألعاب تعليمية بسيطة أو اختبار أفكار جديدة أو تسريع بعض مراحل الإنتاج.&lt;/p&gt;&lt;p&gt;ومع ذلك، فإن تقييم إعلان &lt;strong&gt;جوجل ويونيتي عن Playground&lt;/strong&gt; يتطلب التأكد من التفاصيل الرسمية للمنتج، بما في ذلك موعد الإطلاق، وطريقة الوصول إليه، والأدوات التي يوفرها، ومدى تكامله مع محرك Unity، وحدود الاستخدام المتاحة. ولا ينبغي اعتبار الإمكانات العامة للذكاء الاصطناعي دليلًا على توافر ميزة بعينها في المنتج قبل تأكيدها من مصدر رسمي.&lt;/p&gt;&lt;p&gt;وفي النهاية، قد لا تكون أهم نتيجة لهذا التطور هي أن الذكاء الاصطناعي سيصنع الألعاب بالكامل بدلًا من البشر، بل أنه يمنح عددًا أكبر من الأشخاص فرصة للبدء في تطوير أفكارهم وتجربتها. ومع تحسن الأدوات وتوسع إمكاناتها، يمكن أن تصبح المسافة بين مجرد تخيل لعبة والبدء في بنائها أقصر من أي وقت مضى.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/6387649506126468715/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/google-unity-playground-ai-game-creation.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6387649506126468715" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6387649506126468715" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/google-unity-playground-ai-game-creation.html" rel="alternate" title="جوجل ويونيتي تطلقان Playground لإنشاء ألعاب الفيديو بالذكاء الاصطناعي" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi040v2EOGgR8cQlRCb-Z_YYaif-j5jnkS92bUjL_uEYIRnU4oCLs0a0cJP7GdqyBNmLpXftviHQL0dsQGfRXy_fUMWBjhmKn7Dr5UFoeVa_ThSC5UKpOIyBSrURkyoyPoycks8d5ehvbP-olncnSCMzCFhOabY_i7XzHv0vqjXX5RZsFNZ5wRuC11-uMKO/s72-c/imageedit_2_6296520505.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-5705586405868259931</id><published>2026-10-14T11:05:16.621+03:00</published><updated>2026-10-14T11:05:16.621+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">دليل شامل للمبتدئين عن الراوتر وكيفية نقل البيانات بين الشبكات</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmlwWs8b4KKIBxxXowfyPCxc3yw69mwOXqwcXD5EeNda80DIMFUl74ug65Cm_F05CBixF6q0RIucf4RId1qZOeUSwvG0Lpq3bu88BQkNQOWMp_erZjOA0xayG3H2f7qkaAWWUGqEI5oxHynzU9_W_4ebtTfO8MXCdOWxPBu5lDGjkhSpuw4MHL1FkO9AA9/s640/imageedit_1_2639328084.webp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="دليل شامل للمبتدئين عن الراوتر وكيفية نقل البيانات بين الشبكات" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmlwWs8b4KKIBxxXowfyPCxc3yw69mwOXqwcXD5EeNda80DIMFUl74ug65Cm_F05CBixF6q0RIucf4RId1qZOeUSwvG0Lpq3bu88BQkNQOWMp_erZjOA0xayG3H2f7qkaAWWUGqEI5oxHynzU9_W_4ebtTfO8MXCdOWxPBu5lDGjkhSpuw4MHL1FkO9AA9/s1600/imageedit_1_2639328084.webp" title="دليل شامل للمبتدئين عن الراوتر وكيفية نقل البيانات بين الشبكات" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الراوتر (Router) كيف تنتقل البيانات بين الشبكات؟ دليل شامل للمبتدئين&lt;/h3&gt;
&lt;p&gt;هل تساءلت يومًا كيف يستطيع هاتفك وحاسوبك والتلفاز الذكي الاتصال بالإنترنت في الوقت نفسه؟ وكيف تصل الرسالة التي ترسلها عبر تطبيق واتساب إلى شخص موجود في دولة أخرى؟ وما الجهاز المسؤول عن تحديد الطريق الذي تسلكه البيانات حتى تصل إلى وجهتها الصحيحة؟&lt;/p&gt;
&lt;p&gt;الإجابة تقودنا إلى أحد أهم مكونات البنية التحتية للشبكات، وهو &lt;strong&gt;الراوتر (Router)&lt;/strong&gt;، الذي يؤدي دورًا أساسيًا في ربط الشبكات المختلفة وتوجيه حزم البيانات بينها.&lt;/p&gt;
&lt;p&gt;سواء كنت طالبًا في علوم الحاسوب، أو مهتمًا بمجال الشبكات والأمن السيبراني، أو ترغب في فهم كيفية عمل الإنترنت، فإن معرفة آلية عمل الراوتر ستساعدك على فهم كثير من المفاهيم التقنية التي تستخدمها يوميًا.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما هو الراوتر (Router)؟&lt;/h3&gt;
&lt;p&gt;الراوتر، ويُسمى أيضًا &lt;strong&gt;الموجّه أو الموجّه الشبكي&lt;/strong&gt;، هو جهاز شبكي يعمل على ربط شبكتين أو أكثر، ويوجّه حزم البيانات (Data Packets) من شبكة إلى أخرى اعتمادًا على معلومات عناوين IP وجداول التوجيه.&lt;/p&gt;
&lt;p&gt;تتمثل وظيفته الأساسية في تحديد الواجهة أو المسار المناسب لإرسال حزم البيانات نحو وجهتها، وفقًا للمعلومات المتاحة في جدول التوجيه وسياسات التوجيه المستخدمة.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، عندما يتصل هاتفك بشبكة Wi-Fi المنزلية ويحاول فتح موقع إلكتروني موجود على خادم خارج شبكتك المحلية، يتولى الراوتر عادةً تمرير البيانات نحو الشبكة التالية في الطريق إلى ذلك الخادم.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال من الحياة اليومية&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تخيّل أن منزلك يحتوي على الأجهزة التالية:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;حاسوب محمول يستخدمه أحد أفراد الأسرة.&lt;/li&gt;
&lt;li&gt;هاتف ذكي متصل بشبكة Wi-Fi.&lt;/li&gt;
&lt;li&gt;تلفاز ذكي يعرض مقاطع الفيديو عبر الإنترنت.&lt;/li&gt;
&lt;li&gt;جهاز ألعاب يحتاج إلى اتصال بالشبكة.&lt;/li&gt;
&lt;li&gt;طابعة شبكية تستخدمها عدة أجهزة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;يمكن لهذه الأجهزة الاتصال بالشبكة المحلية نفسها ومشاركة الاتصال بالإنترنت من خلال الراوتر، إذا كانت الشبكة وإعداداتها تسمحان بذلك.&lt;/p&gt;
&lt;p&gt;يشبه الراوتر في هذا المثال مركزًا لتنظيم حركة البيانات، لكنه لا يكتفي بإرسال المعلومات إلى أي جهاز عشوائي؛ بل يعتمد على عناوين الشبكة وقواعد التوجيه لتحديد وجهة الحزم.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;معلومة مهمة:&lt;/strong&gt; لا يعني وجود عدة أجهزة متصلة براوتر واحد أنها تستخدم عنوان IP نفسه. غالبًا ما يحصل كل جهاز على عنوان IP محلي خاص به داخل الشبكة، بينما قد تشترك الأجهزة في عنوان IP عام واحد عند الوصول إلى الإنترنت باستخدام تقنية ترجمة عناوين الشبكة (NAT).&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;كيف يعمل الراوتر؟&lt;/h3&gt;
&lt;p&gt;لفهم آلية عمل الراوتر، لنفترض أنك تستخدم حاسوبك لزيارة موقع إلكتروني موجود على خادم خارج شبكتك المنزلية.&lt;/p&gt;
&lt;p&gt;تمر العملية بعدة مراحل أساسية.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. اتصال الحاسوب بالشبكة المحلية&lt;/h4&gt;
&lt;p&gt;يتصل الحاسوب بالراوتر عن طريق كابل الشبكة Ethernet أو باستخدام شبكة Wi-Fi.&lt;/p&gt;
&lt;p&gt;يحصل الحاسوب عادةً على إعدادات الشبكة من خلال بروتوكول DHCP، الذي قد يوفر له:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;عنوان IP محليًا.&lt;/li&gt;
&lt;li&gt;قناع الشبكة الفرعية (Subnet Mask).&lt;/li&gt;
&lt;li&gt;عنوان البوابة الافتراضية (Default Gateway).&lt;/li&gt;
&lt;li&gt;عنوان خادم DNS أو أكثر.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;قد تُضبط هذه المعلومات يدويًا بدلًا من الحصول عليها تلقائيًا.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. تحديد ما إذا كانت الوجهة محلية أم خارج الشبكة&lt;/h4&gt;
&lt;p&gt;عندما يريد الحاسوب إرسال بيانات إلى عنوان IP معين، فإنه يستخدم عنوان IP الخاص بالوجهة وقناع الشبكة الفرعية لتحديد ما إذا كانت الوجهة ضمن الشبكة المحلية نفسها أم خارجها.&lt;/p&gt;
&lt;p&gt;إذا كانت الوجهة داخل الشبكة المحلية، فقد يرسل الحاسوب البيانات إليها مباشرةً على مستوى الشبكة المحلية.&lt;/p&gt;
&lt;p&gt;أما إذا كانت الوجهة خارج الشبكة المحلية، فإنه يرسل الحزم عادةً إلى البوابة الافتراضية.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. إرسال البيانات إلى البوابة الافتراضية&lt;/h4&gt;
&lt;p&gt;البوابة الافتراضية (Default Gateway) هي عنوان جهاز التوجيه الذي يستخدمه الحاسوب للوصول إلى الوجهات التي لا يستطيع الوصول إليها مباشرةً ضمن شبكته المحلية.&lt;/p&gt;
&lt;p&gt;في الشبكات المنزلية، تكون هذه البوابة غالبًا عنوانًا محليًا للراوتر، مثل:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;لكن هذا العنوان ليس ثابتًا لجميع الشبكات؛ فقد يكون عنوان الراوتر &lt;code&gt;192.168.0.1&lt;/code&gt; أو عنوانًا آخر حسب إعدادات الشبكة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;4. فحص عنوان IP للوجهة&lt;/h4&gt;
&lt;p&gt;عندما يستقبل الراوتر حزمة البيانات، يفحص عنوان IP الخاص بالوجهة الموجود في ترويسة حزمة IP.&lt;/p&gt;
&lt;p&gt;بعد ذلك، يبحث عن المسار المناسب في جدول التوجيه (Routing Table).&lt;/p&gt;
&lt;p&gt;لا يعتمد قرار التوجيه على عنوان IP وحده في جميع الحالات؛ فقد تؤثر أيضًا عوامل مثل طول بادئة الشبكة، ومقاييس المسارات، وسياسات التوجيه.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;5. اختيار المسار المناسب&lt;/h4&gt;
&lt;p&gt;يحتوي جدول التوجيه على معلومات تساعد الراوتر في تحديد كيفية الوصول إلى شبكات الوجهة.&lt;/p&gt;
&lt;p&gt;وقد تتضمن هذه المعلومات:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;شبكة الوجهة.&lt;/li&gt;
&lt;li&gt;طول بادئة الشبكة (Prefix Length).&lt;/li&gt;
&lt;li&gt;القفزة التالية (Next Hop)، إن وجدت.&lt;/li&gt;
&lt;li&gt;واجهة الخروج المناسبة.&lt;/li&gt;
&lt;li&gt;معلومات إضافية تتعلق بمصدر المسار ومقياسه.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;إذا وجد الراوتر أكثر من مسار مطابق لعنوان الوجهة، فإنه يستخدم قواعد اختيار المسار المناسبة، ومن أهمها مبدأ &lt;strong&gt;أطول بادئة مطابقة (Longest Prefix Match)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;بمعنى آخر، يُفضّل عادةً المسار الذي يحدد شبكة الوجهة بأكبر قدر من الدقة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;6. تمرير الحزمة إلى الشبكة التالية&lt;/h4&gt;
&lt;p&gt;بعد اختيار المسار، يمرّر الراوتر الحزمة عبر واجهة الخروج المناسبة، وقد يرسلها إلى راوتر آخر يمثل القفزة التالية.&lt;/p&gt;
&lt;p&gt;تتكرر هذه العملية عبر عدد من الشبكات والموجّهات حتى تصل البيانات إلى الشبكة التي يوجد فيها الخادم المستهدف.&lt;/p&gt;
&lt;p&gt;وقد تمر البيانات عبر عدة موجّهات مستقلة قبل بلوغ وجهتها.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;7. وصول البيانات إلى الخادم&lt;/h4&gt;
&lt;p&gt;عندما تصل الحزمة إلى الشبكة التي يوجد فيها الخادم، يتم توجيهها إلى الوجهة النهائية.&lt;/p&gt;
&lt;p&gt;يرسل الخادم بعد ذلك البيانات المطلوبة، وتعود الاستجابة عبر مسار قد يكون مماثلًا للمسار الأصلي أو مختلفًا عنه.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;الخلاصة:&lt;/strong&gt; لا يحتاج الراوتر المنزلي إلى معرفة الطريق الكامل حتى الخادم البعيد؛ بل يحدد عادةً الخطوة التالية المناسبة اعتمادًا على جدول التوجيه الخاص به.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما هو جدول التوجيه (Routing Table)؟&lt;/h3&gt;
&lt;p&gt;جدول التوجيه هو أحد أهم العناصر التي يعتمد عليها الراوتر لاتخاذ قرارات تمرير البيانات.&lt;/p&gt;
&lt;p&gt;ويمكن تشبيهه بخريطة تحتوي على معلومات عن الشبكات المختلفة والطرق المتاحة للوصول إليها.&lt;/p&gt;
&lt;p&gt;قد يحتوي جدول التوجيه على مسارات مثل:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;شبكة الوجهة&lt;/th&gt;
&lt;th&gt;القفزة التالية&lt;/th&gt;
&lt;th&gt;واجهة الخروج&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;الشبكة المحلية&lt;/td&gt;
&lt;td&gt;اتصال مباشر&lt;/td&gt;
&lt;td&gt;LAN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;شبكة بعيدة&lt;/td&gt;
&lt;td&gt;راوتر وسيط&lt;/td&gt;
&lt;td&gt;WAN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;المسار الافتراضي&lt;/td&gt;
&lt;td&gt;بوابة مزود الخدمة&lt;/td&gt;
&lt;td&gt;WAN&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;هذا الجدول توضيحي فقط، وليس جدولًا حقيقيًا خاصًا بجهاز معين.&lt;/p&gt;
&lt;h3&gt;ما المقصود بالمسار الافتراضي؟&lt;/h3&gt;
&lt;p&gt;المسار الافتراضي (Default Route) هو المسار الذي يستخدمه الراوتر عندما لا يجد مسارًا أكثر تحديدًا لعنوان الوجهة.&lt;/p&gt;
&lt;p&gt;في IPv4، يُكتب عادةً بالشكل التالي:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;0.0.0.0/0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;أما في IPv6، فيُكتب بالشكل التالي:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;::/0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;في كثير من الشبكات المنزلية، يرسل الراوتر حركة البيانات المتجهة إلى الإنترنت عبر المسار الافتراضي المؤدي إلى جهاز مزود خدمة الإنترنت.&lt;/p&gt;
&lt;h3&gt;كيف يتعلم الراوتر المسارات؟&lt;/h3&gt;
&lt;p&gt;يمكن للراوتر الحصول على معلومات المسارات بطرق مختلفة، منها:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;المسارات المتصلة مباشرةً (Connected Routes):&lt;/strong&gt; تنشأ عندما تكون إحدى الشبكات متصلة مباشرةً بإحدى واجهات الراوتر وتكون الواجهة مهيأة وتعمل.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;المسارات الثابتة (Static Routes):&lt;/strong&gt; يضيفها مسؤول الشبكة يدويًا.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;بروتوكولات التوجيه الديناميكي (Dynamic Routing Protocols):&lt;/strong&gt; تسمح للموجّهات بتبادل معلومات المسارات وتحديثها وفقًا للبروتوكول المستخدم.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ومن أمثلة بروتوكولات التوجيه الديناميكي:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;OSPF: يُستخدم لتبادل معلومات التوجيه داخل الأنظمة المستقلة الإدارية.&lt;/li&gt;
&lt;li&gt;BGP: يُستخدم لتبادل معلومات التوجيه بين الأنظمة المستقلة، وله دور أساسي في توجيه حركة البيانات على الإنترنت.&lt;/li&gt;
&lt;li&gt;RIP: بروتوكول توجيه يستخدم عدد القفزات مقياسًا أساسيًا لاختيار المسار، ويُعد أبسط من بروتوكولات أخرى من حيث آلية اختيار المسار.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;لا تحتاج الشبكات المنزلية البسيطة عادةً إلى إعداد بروتوكولات التوجيه الديناميكي يدويًا.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما أهم وظائف الراوتر؟&lt;/h3&gt;
&lt;p&gt;يؤدي الراوتر وظائف متعددة، لكن يجب التمييز بين وظيفته الأساسية والخدمات الإضافية التي قد تتوفر في الأجهزة المنزلية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;1. توجيه حزم البيانات&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;هذه هي الوظيفة الأساسية للراوتر، إذ يحدد كيفية تمرير الحزم بين الشبكات المختلفة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;2. ربط الشبكة المحلية بالإنترنت&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يُستخدم الراوتر المنزلي عادةً لربط الشبكة المحلية بشبكة مزود خدمة الإنترنت، عندما تكون خدمة الاتصال وإعدادات الجهاز متوافقة مع ذلك.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;3. مشاركة الاتصال بالإنترنت&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يمكن لعدة أجهزة استخدام اتصال إنترنت واحد من خلال الراوتر.&lt;/p&gt;
&lt;p&gt;وتُستخدم تقنية ترجمة عناوين الشبكة (NAT) في كثير من الشبكات المنزلية لتمكين أجهزة ذات عناوين IPv4 محلية من مشاركة عنوان IPv4 عام واحد.&lt;/p&gt;
&lt;p&gt;لكن NAT ليست وظيفة أساسية إلزامية في كل راوتر، كما أنها ليست شرطًا عامًا لعمل التوجيه.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;4. توفير شبكة Wi-Fi&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تحتوي كثير من أجهزة الراوتر المنزلية على نقطة وصول لاسلكية (Wireless Access Point)، تسمح للأجهزة بالاتصال بالشبكة دون الحاجة إلى كابلات.&lt;/p&gt;
&lt;p&gt;لكن وظيفة Wi-Fi ليست جزءًا ضروريًا من تعريف الراوتر نفسه؛ إذ توجد موجّهات سلكية لا توفر اتصالًا لاسلكيًا.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;5. توزيع عناوين IP باستخدام DHCP&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يدعم كثير من الراوترات المنزلية خادم DHCP الذي يوزع إعدادات الشبكة على الأجهزة المتصلة.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، قد يحصل الحاسوب على عنوان:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.10&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;بينما يحصل الهاتف على عنوان:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.11&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;ويكون عنوان البوابة الافتراضية لكليهما:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;هذه العناوين أمثلة توضيحية، وقد تختلف القيم الفعلية حسب إعدادات الشبكة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;6. توفير بعض وظائف الأمان&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;قد تتضمن أجهزة الراوتر المنزلية ميزات أمنية مثل:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;جدار حماية لحركة البيانات.&lt;/li&gt;
&lt;li&gt;قواعد للتحكم في الاتصالات الواردة والصادرة.&lt;/li&gt;
&lt;li&gt;شبكات ضيوف منفصلة.&lt;/li&gt;
&lt;li&gt;خيارات لتصفية الأجهزة أو الاتصالات.&lt;/li&gt;
&lt;li&gt;إعدادات للتحكم الأبوي.&lt;/li&gt;
&lt;li&gt;دعم شبكات VPN في بعض الطرازات.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;تختلف هذه الميزات حسب نوع الجهاز ونظام تشغيله وإعداداته.&lt;/p&gt;
&lt;p&gt;ومن المهم معرفة أن وجود الراوتر وحده لا يضمن الحماية الكاملة؛ إذ يجب تحديث برامجه الثابتة واستخدام كلمات مرور قوية وضبط إعداداته بصورة صحيحة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما الفرق بين Router وModem وSwitch وAccess Point؟&lt;/h3&gt;
&lt;p&gt;من الأخطاء الشائعة الاعتقاد بأن هذه الأجهزة تؤدي الوظيفة نفسها، مع أن لكل جهاز دورًا مختلفًا في الشبكة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;1. الراوتر (Router)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يربط الشبكات المختلفة ويوجه حزم IP بينها.&lt;/p&gt;
&lt;p&gt;مثال: توجيه البيانات من شبكة منزلك المحلية نحو الإنترنت.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;2. المودم (Modem)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يتعامل مع تقنية الاتصال المستخدمة لنقل البيانات عبر وصلة مزود الخدمة، وفقًا لنوع الاتصال.&lt;/p&gt;
&lt;p&gt;قد يستخدم الاتصال تقنيات DSL أو الكابل أو غيرها، بينما تُستخدم أجهزة ONT عادةً في اتصالات الألياف الضوئية لإنهاء الوصلة الضوئية وتحويل الإشارة إلى واجهة مناسبة للأجهزة الأخرى.&lt;/p&gt;
&lt;p&gt;ولا يُعد ONT مجرد اسم آخر للمودم التقليدي؛ إذ تختلف آلية عمله بحسب تقنية الاتصال.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;3. السويتش (Switch)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يُستخدم السويتش لربط الأجهزة داخل الشبكة المحلية، ويعتمد عادةً على عناوين MAC لتمرير إطارات Ethernet إلى المنافذ المناسبة.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، يمكن استخدام السويتش لربط عدة حواسيب وطابعات وأجهزة شبكية ضمن شبكة محلية واحدة.&lt;/p&gt;
&lt;p&gt;توجد سويتشات من الطبقة الثانية تعمل أساسًا على تمرير الإطارات، كما توجد سويتشات من الطبقة الثالثة تستطيع تنفيذ بعض وظائف التوجيه.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;4. نقطة الوصول اللاسلكية (Access Point)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تتيح نقطة الوصول للأجهزة الاتصال بالشبكة المحلية لاسلكيًا عبر Wi-Fi.&lt;/p&gt;
&lt;p&gt;قد تكون جهازًا مستقلًا يُوصل براوتر أو سويتش، أو وظيفة مدمجة داخل الراوتر المنزلي.&lt;/p&gt;
&lt;h3&gt;مقارنة سريعة&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;الجهاز&lt;/th&gt;
&lt;th&gt;الوظيفة الأساسية&lt;/th&gt;
&lt;th&gt;مثال على الاستخدام&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Router&lt;/td&gt;
&lt;td&gt;توجيه البيانات بين الشبكات&lt;/td&gt;
&lt;td&gt;ربط المنزل بالإنترنت&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Modem&lt;/td&gt;
&lt;td&gt;التعامل مع تقنية وصلة الاتصال&lt;/td&gt;
&lt;td&gt;الاتصال عبر خدمة DSL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch&lt;/td&gt;
&lt;td&gt;ربط الأجهزة داخل الشبكة المحلية&lt;/td&gt;
&lt;td&gt;ربط حواسيب مختبر&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Access Point&lt;/td&gt;
&lt;td&gt;توفير الاتصال اللاسلكي بالشبكة&lt;/td&gt;
&lt;td&gt;توسيع تغطية Wi-Fi&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;ملاحظة:&lt;/strong&gt; قد يجمع جهاز واحد بين الراوتر والمودم والسويتش ونقطة الوصول اللاسلكية، لكن ذلك لا يعني أن هذه الوظائف متطابقة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;هل كل راوتر يوفر اتصال Wi-Fi؟&lt;/h3&gt;
&lt;p&gt;الإجابة: لا.&lt;/p&gt;
&lt;p&gt;توجد موجّهات سلكية وأخرى لاسلكية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الراوتر السلكي (Wired Router)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يوجه البيانات بين الشبكات باستخدام واجهات اتصال سلكية.&lt;/p&gt;
&lt;p&gt;يمكن استخدامه في المؤسسات ومراكز البيانات والشبكات التي تحتاج إلى أداء مستقر وإدارة متقدمة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الراوتر اللاسلكي (Wireless Router)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يجمع عادةً بين وظيفتين أساسيتين:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;توجيه البيانات بين الشبكات.&lt;/li&gt;
&lt;li&gt;توفير نقطة وصول لاسلكية تسمح للأجهزة بالاتصال عبر Wi-Fi.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;تحتوي بعض الأجهزة المنزلية أيضًا على منافذ Ethernet مدمجة لربط الأجهزة السلكية.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما أنواع الراوترات؟&lt;/h3&gt;
&lt;p&gt;تختلف الراوترات بحسب الاستخدام والحجم والقدرات التقنية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;الراوتر المنزلي (Home Router) :&amp;nbsp;&lt;/b&gt;يُستخدم في المنازل والشقق الصغيرة، ويوفر عادةً الاتصال بين الشبكة المحلية والإنترنت.وقد يضم وظائف DHCP وNAT وجدار الحماية ونقطة الوصول اللاسلكية.&lt;/li&gt;&lt;li&gt;&lt;b&gt;راوتر الشركات (Enterprise Router) :&amp;nbsp;&lt;/b&gt;يُستخدم في المؤسسات التي تحتاج إلى ربط عدة شبكات ومواقع جغرافية مختلفة.قد يدعم ميزات متقدمة مثل بروتوكولات التوجيه الديناميكي، وإدارة السياسات، والربط بين الفروع، والاتصالات الاحتياطية.&lt;/li&gt;&lt;li&gt;&lt;b&gt;راوتر مزود خدمة الإنترنت (ISP Router) :&amp;nbsp;&lt;/b&gt;يستخدمه مزودو خدمات الإنترنت لتوجيه حركة البيانات بين شبكاتهم وشبكات أخرى. وتختلف إمكاناته وحجمه وفقًا لمتطلبات الشبكة وعدد الاتصالات وحجم حركة البيانات.&lt;/li&gt;&lt;li&gt;&lt;b&gt;الراوتر الافتراضي (Virtual Router) :&amp;nbsp;&lt;/b&gt;هو وظيفة توجيه تعمل باستخدام البرمجيات داخل خادم أو منصة افتراضية بدلًا من الاعتماد حصريًا على جهاز مخصص. يمكن استخدامه في البيئات السحابية ومراكز البيانات ومختبرات الشبكات.&lt;/li&gt;&lt;li&gt;&lt;b&gt;راوتر الألعاب :&amp;nbsp;&lt;/b&gt;هو راوتر يُسوّق للاستخدام مع الألعاب عبر الإنترنت، وقد يوفر ميزات لإدارة جودة الخدمة (QoS) أو إعطاء أولوية لأنواع معينة من حركة البيانات. لكن وجود هذه الميزات لا يضمن دائمًا انخفاض زمن الاستجابة؛ فالنتيجة تعتمد أيضًا على جودة الاتصال بالإنترنت، وازدحام الشبكة، وموقع خادم اللعبة.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;




&lt;h3 style="text-align: right;"&gt;ما المقصود بعنوان IP وعلاقته بالراوتر؟&lt;/h3&gt;
&lt;p&gt;عنوان IP هو عنوان منطقي يُستخدم لتحديد واجهة الشبكة ومساعدة بروتوكولات الإنترنت على إيصال الحزم إلى وجهتها.&lt;/p&gt;
&lt;p&gt;يوجد إصداران رئيسيان من بروتوكول الإنترنت:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;IPv4.&lt;/li&gt;
&lt;li&gt;IPv6.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال على شبكة منزلية&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;لنفترض أن لدينا الشبكة التالية:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;عنوان الراوتر المحلي: &lt;code&gt;192.168.1.1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;عنوان الحاسوب: &lt;code&gt;192.168.1.10&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;عنوان الهاتف: &lt;code&gt;192.168.1.11&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;عنوان الطابعة: &lt;code&gt;192.168.1.20&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;قد تستخدم هذه الأجهزة قناع الشبكة التالي:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;255.255.255.0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;وهو ما يقابل البادئة:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.0/24&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;في هذا المثال، تقع عناوين الأجهزة المذكورة ضمن الشبكة المحلية نفسها.&lt;/p&gt;
&lt;p&gt;إذا أراد الحاسوب التواصل مع وجهة خارج هذه الشبكة، فإنه يرسل الحزم عادةً إلى البوابة الافتراضية، أي الراوتر.&lt;/p&gt;
&lt;p&gt;لكن إذا أراد التواصل مع جهاز آخر ضمن الشبكة المحلية نفسها، فقد يتمكن من إرسال البيانات إليه مباشرةً دون المرور عبر وظيفة التوجيه في الراوتر.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما الفرق بين عنوان IP المحلي والعام؟&lt;/h3&gt;
&lt;p&gt;لفهم طريقة عمل الراوتر المنزلي، يجب التمييز بين نوعين شائعين من عناوين IPv4.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;عنوان IP المحلي (Private IP)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;هو عنوان يُستخدم داخل الشبكات الخاصة، مثل الشبكات المنزلية وشبكات المؤسسات.&lt;/p&gt;
&lt;p&gt;تشمل نطاقات IPv4 الخاصة ما يلي:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;10.0.0.0/8&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;172.16.0.0/12&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;192.168.0.0/16&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;يمكن استخدام هذه العناوين في شبكات متعددة ومستقلة، ولذلك لا يلزم أن يكون عنوان الجهاز المحلي فريدًا على مستوى الإنترنت كله.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;عنوان IP العام (Public IP)&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;هو عنوان قابل للاستخدام في التوجيه عبر الإنترنت العام، وفقًا لقواعد تخصيص العناوين والتوجيه.&lt;/p&gt;
&lt;p&gt;في كثير من الشبكات المنزلية، يحصل الراوتر على عنوان IPv4 عام من مزود خدمة الإنترنت، بينما تستخدم الأجهزة داخل المنزل عناوين خاصة.&lt;/p&gt;
&lt;p&gt;وتساعد تقنية NAT على ترجمة معلومات العناوين والمنافذ بين الاتصالات المحلية والخارجية.&lt;/p&gt;
&lt;p&gt;لكن بعض الشبكات تستخدم آليات مختلفة، مثل ترجمة عناوين الناقل (CGNAT)، وقد لا يحصل الراوتر المنزلي فيها على عنوان IPv4 عام مخصص له مباشرةً.&lt;/p&gt;
&lt;p&gt;وفي شبكات IPv6، يمكن أن تحصل الأجهزة على عناوين عالمية قابلة للتوجيه، ولا تكون ترجمة عناوين الشبكة NAT مطلوبة بالطريقة نفسها لمجرد مشاركة الاتصال.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما هي تقنية NAT؟ وما علاقتها بالراوتر؟&lt;/h3&gt;
&lt;p&gt;NAT اختصار لعبارة Network Address Translation، وتعني ترجمة عناوين الشبكة.&lt;/p&gt;
&lt;p&gt;تُستخدم هذه التقنية لتعديل معلومات عناوين IP، وقد تشمل المنافذ أيضًا، عند انتقال حركة البيانات بين نطاقات الشبكة المختلفة.&lt;/p&gt;
&lt;p&gt;في الشبكات المنزلية التي تستخدم IPv4، تُستخدم غالبًا ترجمة عناوين المنافذ (PAT أو NAPT) للسماح لعدة أجهزة بمشاركة عنوان IPv4 عام واحد.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال مبسط&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;لنفترض أن لديك ثلاثة أجهزة:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;حاسوب بعنوان &lt;code&gt;192.168.1.10&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;هاتف بعنوان &lt;code&gt;192.168.1.11&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;تلفاز ذكي بعنوان &lt;code&gt;192.168.1.12&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;عندما تتصل هذه الأجهزة بخوادم خارج الشبكة، قد يستخدم الراوتر ترجمة العناوين والمنافذ حتى يتمكن من تمييز الاتصالات وإعادة توجيه الردود إلى الأجهزة الصحيحة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;هل NAT هي نفسها وظيفة التوجيه؟&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;لا. التوجيه يحدد كيفية تمرير الحزمة نحو الشبكة التالية، بينما تتعامل NAT مع ترجمة معلومات العناوين، وقد تتضمن ترجمة المنافذ.&lt;/p&gt;
&lt;p&gt;يمكن أن يجمع جهاز واحد بين الوظيفتين، لكنهما عمليتان مختلفتان من الناحية التقنية.&lt;/p&gt;
&lt;p&gt;كذلك، لا تُعد NAT جدار حماية بحد ذاتها، حتى لو ساهمت بعض سلوكياتها في منع الاتصالات الواردة غير المرتبطة باتصالات سابقة في إعدادات معينة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما المقصود بالبوابة الافتراضية (Default Gateway)؟&lt;/h3&gt;
&lt;p&gt;البوابة الافتراضية هي الجهاز الذي يرسل إليه الحاسوب البيانات عندما تكون الوجهة خارج الشبكة المحلية ولا يوجد مسار أكثر تحديدًا ينطبق عليها.&lt;/p&gt;
&lt;p&gt;في الشبكات المنزلية، تكون البوابة الافتراضية عادةً عنوان الراوتر المحلي.&lt;/p&gt;
&lt;p&gt;على سبيل المثال:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;إذا كان عنوان حاسوبك:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.10&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;وكانت البوابة الافتراضية:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;فإن الحاسوب يستخدم عنوان البوابة للوصول إلى الوجهات الخارجية، وفقًا لجدول التوجيه وإعدادات الشبكة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;ماذا يحدث إذا كانت البوابة الافتراضية غير صحيحة؟&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;قد يتمكن الحاسوب من التواصل مع بعض الأجهزة المحلية، لكنه يفشل في الوصول إلى الشبكات الخارجية.&lt;/p&gt;
&lt;p&gt;ومن الأسباب المحتملة:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;إدخال عنوان بوابة غير صحيح.&lt;/li&gt;
&lt;li&gt;تعطل الراوتر.&lt;/li&gt;
&lt;li&gt;وجود مشكلة في إعدادات الشبكة.&lt;/li&gt;
&lt;li&gt;عدم توفر مسار مناسب إلى الإنترنت.&lt;/li&gt;
&lt;li&gt;وجود خلل في وصلة مزود الخدمة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;لهذا السبب، يُعد فحص البوابة الافتراضية خطوة مفيدة عند تشخيص مشكلات الاتصال.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;كيف يفحص الراوتر حزم البيانات؟&lt;/h3&gt;
&lt;p&gt;تتكون حزمة IP من ترويسة تحتوي على معلومات لازمة لعملية التوجيه، إضافةً إلى البيانات التي تحملها.&lt;/p&gt;
&lt;p&gt;ومن المعلومات المهمة في ترويسة IPv4:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;عنوان IP للمصدر.&lt;/li&gt;
&lt;li&gt;عنوان IP للوجهة.&lt;/li&gt;
&lt;li&gt;حقل مدة البقاء (TTL).&lt;/li&gt;
&lt;li&gt;معلومات أخرى تتعلق بطول الحزمة والتجزئة وغيرها.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;أما في IPv6، فيُستخدم حقل Hop Limit بدلًا من TTL.&lt;/p&gt;
&lt;p&gt;عندما يمرر الراوتر حزمة IPv4، فإنه يُنقص قيمة TTL عادةً بمقدار واحد. وإذا وصلت القيمة إلى الصفر، لا تُمرر الحزمة إلى القفزة التالية، ويُتوقع عادةً إرسال رسالة ICMP مناسبة وفقًا للظروف.&lt;/p&gt;
&lt;p&gt;تساعد هذه الآلية على منع الحزم من الدوران إلى ما لا نهاية نتيجة وجود حلقات في التوجيه.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;هل يقرأ الراوتر محتوى كل رسالة؟&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;ليس من الضروري أن يقرأ الراوتر محتوى الرسائل أو صفحات الويب كي يوجّه الحزم.&lt;/p&gt;
&lt;p&gt;تعتمد وظيفة التوجيه الأساسية على معلومات طبقة الشبكة، خصوصًا عنوان IP للوجهة.&lt;/p&gt;
&lt;p&gt;أما فحص المحتوى أو تطبيق سياسات متقدمة على حركة البيانات، فيعتمد على نوع الجهاز والميزات المفعلة والبروتوكولات المستخدمة.&lt;/p&gt;
&lt;p&gt;وعندما تكون الاتصالات مشفرة باستخدام HTTPS، يكون محتوى الاتصال محميًا بالتشفير أثناء النقل، مع بقاء بعض معلومات الاتصال الوصفية متاحة بحسب البروتوكول والظروف.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما العلاقة بين الراوتر وDNS؟&lt;/h3&gt;
&lt;p&gt;DNS اختصار لـ Domain Name System، وهو نظام يُستخدم لتحويل أسماء النطاقات، مثل أسماء المواقع الإلكترونية، إلى معلومات يمكن للأجهزة استخدامها للوصول إلى الوجهات، ومنها عناوين IP.&lt;/p&gt;
&lt;p&gt;عندما تكتب اسم موقع في المتصفح، يحتاج الجهاز عادةً إلى حل اسم النطاق قبل الاتصال بالخادم.&lt;/p&gt;
&lt;p&gt;وقد يتلقى الحاسوب عنوان خادم DNS من خلال DHCP، ويمكن أن يكون هذا الخادم:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;الراوتر المنزلي، إذا كان يعمل وسيطًا لطلبات DNS.&lt;/li&gt;
&lt;li&gt;خادمًا تابعًا لمزود خدمة الإنترنت.&lt;/li&gt;
&lt;li&gt;خادم DNS عامًا أو خاصًا يختاره المستخدم.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;هل الراوتر هو الذي يحوّل اسم الموقع إلى عنوان IP؟&lt;/h3&gt;
&lt;p&gt;ليس بالضرورة. قد يمرر الراوتر حزم DNS، أو يقدم خدمة وسيطة لطلبات DNS، لكن حل أسماء النطاقات وظيفة منفصلة عن التوجيه.&lt;/p&gt;
&lt;p&gt;من المهم فهم الفرق بين العمليتين:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DNS:&lt;/strong&gt; يساعد على تحديد عنوان الوجهة انطلاقًا من اسم النطاق.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Routing:&lt;/strong&gt; يحدد كيفية تمرير حزم IP نحو شبكة الوجهة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;وقد تتوقف زيارة موقع إلكتروني بسبب مشكلة في DNS حتى لو كان الاتصال الأساسي بالشبكة يعمل بصورة سليمة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما العلاقة بين الراوتر والأمن السيبراني؟&lt;/h3&gt;
&lt;p&gt;يُعد الراوتر من المكونات المهمة في أمن الشبكات، لأنه يقع غالبًا عند نقطة الاتصال بين الشبكة المحلية والشبكات الخارجية.&lt;/p&gt;
&lt;p&gt;إذا كانت إعداداته ضعيفة أو برامجه غير محدثة، فقد يصبح نقطة دخول يستغلها المهاجمون للوصول إلى الشبكة أو تعطيل الاتصال.&lt;/p&gt;
&lt;h3&gt;أهم الإجراءات لحماية الراوتر&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;1. تغيير كلمة مرور الإدارة الافتراضية&amp;nbsp;&lt;/strong&gt;: لا تستخدم بيانات الدخول الافتراضية التي يسهل تخمينها، واضبط كلمة مرور قوية وفريدة لإدارة الجهاز.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. تحديث البرنامج الثابت (Firmware)&lt;/strong&gt;&amp;nbsp;: تساعد التحديثات الأمنية على إصلاح الثغرات وتحسين استقرار الجهاز.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. استخدام تشفير Wi-Fi قوي&lt;/strong&gt;&amp;nbsp;: استخدم WPA3 عند توفره ودعم الأجهزة له، أو WPA2-AES إذا كان ذلك هو الخيار الآمن المتاح على جهازك.تجنب أنماط الحماية القديمة أو الشبكات المفتوحة عند عدم وجود حاجة إليها.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. تعطيل الإدارة عن بُعد إذا لم تكن بحاجة إليها&lt;/strong&gt;&amp;nbsp;: قد يؤدي ترك واجهة الإدارة متاحة من الإنترنت إلى زيادة المخاطر، خصوصًا إذا كانت الحماية ضعيفة أو كان الجهاز يحتوي على ثغرات.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. تعطيل WPS إذا لم تكن تستخدمه&lt;/strong&gt;&amp;nbsp;: قد يؤدي تعطيل هذه الميزة إلى تقليل بعض المخاطر المرتبطة بطرق الاتصال السهلة، بحسب نوع الجهاز وطريقة تنفيذ الميزة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. استخدام شبكة ضيوف&lt;/strong&gt;&amp;nbsp;: يمكن لشبكة الضيوف فصل أجهزة الزوار عن بعض الأجهزة الموجودة في الشبكة الرئيسية، بشرط ضبط العزل بصورة صحيحة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. مراجعة الأجهزة المتصلة&lt;/strong&gt;&amp;nbsp;: افحص قائمة الأجهزة المتصلة بالراوتر من وقت إلى آخر، وتحقق من الأجهزة التي لا تعرفها.&lt;/p&gt;
&lt;p&gt;وجود جهاز غير مألوف لا يثبت وحده وجود اختراق؛ فقد يكون جهازًا قديمًا أو هاتفًا باسم مختلف.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;8. تعطيل الخدمات غير الضرورية&lt;/strong&gt;&amp;nbsp;: عطّل الخدمات التي لا تحتاج إليها، مثل بعض خدمات الإدارة أو فتح المنافذ غير المستخدمة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;9. مراجعة قواعد تحويل المنافذ&lt;/strong&gt;&amp;nbsp;: لا تفتح المنافذ أو تحوّلها إلى أجهزة داخل الشبكة دون فهم الغرض منها والمخاطر المترتبة عليها.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;هل وجود الراوتر يعني أن الشبكة محمية تمامًا؟&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;لا. يمكن للراوتر أن يوفر طبقات مهمة من الحماية، لكنه لا يمنع جميع أنواع الهجمات.&lt;/p&gt;
&lt;p&gt;تعتمد الحماية على تحديثات الجهاز، وقوة كلمات المرور، وإعدادات الشبكة، وأمان الأجهزة المتصلة، وسلوك المستخدمين.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;كيف تعرف عنوان الراوتر في Windows؟&lt;/h3&gt;
&lt;p&gt;يمكنك معرفة عنوان البوابة الافتراضية في نظام Windows باستخدام موجه الأوامر CMD.&lt;/p&gt;
&lt;p&gt;اتبع الخطوات التالية:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;الخطوة الأولى:&lt;/strong&gt; اضغط على مفتاحي Windows + R.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;الخطوة الثانية:&lt;/strong&gt; اكتب الأمر التالي:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;cmd&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;ثم اضغط Enter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;الخطوة الثالثة:&lt;/strong&gt; اكتب الأمر:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;ipconfig&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;ثم اضغط Enter.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;الخطوة الرابعة:&lt;/strong&gt; ابحث عن محول الشبكة الذي تستخدمه حاليًا، سواء كان Wi-Fi أو Ethernet.&lt;/p&gt;
&lt;p&gt;ستجد سطرًا باسم:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;Default Gateway&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;وقد يظهر مثلًا بالشكل التالي:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;Default Gateway . . . . . : 192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;هذا العنوان هو البوابة الافتراضية المستخدمة في إعداد الشبكة المعروضة، وقد يختلف عنوانها الفعلي حسب تكوين شبكتك.&lt;/p&gt;
&lt;p&gt;إذا ظهر أكثر من محول شبكة، فقد تجد أكثر من عنوان بوابة افتراضية. ركّز على المحول المستخدم في اتصالك الحالي.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;أوامر عملية لاختبار الاتصال بالراوتر&lt;/h3&gt;
&lt;p&gt;بعد معرفة عنوان البوابة الافتراضية، يمكنك تجربة مجموعة من الأوامر المفيدة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. اختبار الاتصال بالراوتر باستخدام ping&lt;/h4&gt;
&lt;p&gt;اكتب الأمر التالي، مع استبدال العنوان بعنوان الراوتر لديك إذا كان مختلفًا:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;ping 192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;إذا استقبل الحاسوب ردودًا، فهذا يعني أن الجهاز يستطيع الوصول إلى البوابة عبر ICMP في تلك اللحظة.&lt;/p&gt;
&lt;p&gt;لكن عدم وصول الردود لا يعني بالضرورة أن الراوتر معطل؛ فقد تمنع إعداداته الاستجابة لطلبات ICMP.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. فحص المسار باستخدام tracert&lt;/h4&gt;
&lt;p&gt;في Windows، اكتب:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;tracert 8.8.8.8&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;يحاول الأمر عرض الموجّهات الوسيطة التي تمر عبرها الحزم في طريقها إلى عنوان الوجهة.&lt;/p&gt;
&lt;p&gt;قد تظهر بعض القفزات بعلامات النجمة إذا لم تصل الردود في الوقت المحدد، ولا يعني ذلك وحده وجود خلل في الاتصال؛ فقد تكون بعض الموجّهات مهيأة لتقييد رسائل ICMP أو عدم الرد عليها.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. عرض جدول التوجيه&lt;/h4&gt;
&lt;p&gt;اكتب الأمر:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;route print&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;يعرض هذا الأمر جدول التوجيه في Windows، بما في ذلك المسارات المتاحة وعناوين البوابات المرتبطة بها.&lt;/p&gt;
&lt;p&gt;يساعدك ذلك على فهم كيفية اختيار الحاسوب للواجهة أو البوابة المستخدمة للوصول إلى الوجهات المختلفة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;4. عرض إعدادات الشبكة&lt;/h4&gt;
&lt;p&gt;يمكنك استخدام:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;ipconfig /all&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;يعرض الأمر معلومات أكثر تفصيلًا عن إعدادات الشبكة، مثل عناوين IP وعناوين خوادم DNS وDHCP والبوابات الافتراضية، بحسب نوع المحول وإعداداته.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;تنبيه:&lt;/strong&gt; لا تنشر المخرجات الكاملة لهذه الأوامر علنًا دون مراجعتها؛ فقد تتضمن معلومات عن شبكتك أو محولات الاتصال المستخدمة لديك.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما الفرق بين التوجيه الثابت والتوجيه الديناميكي؟&lt;/h3&gt;
&lt;p&gt;يمكن تقسيم طرق توفير معلومات التوجيه إلى أسلوبين شائعين.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;التوجيه الثابت (Static Routing)&lt;/h4&gt;
&lt;p&gt;في هذا الأسلوب، يحدد مسؤول الشبكة المسارات يدويًا.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;المميزات:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;سهل الفهم في الشبكات الصغيرة.&lt;/li&gt;
&lt;li&gt;لا يحتاج إلى تبادل معلومات التوجيه باستخدام بروتوكول ديناميكي.&lt;/li&gt;
&lt;li&gt;يوفر تحكمًا مباشرًا في المسارات المحددة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;العيوب:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;يتطلب تعديلات يدوية عند تغير بنية الشبكة.&lt;/li&gt;
&lt;li&gt;قد يصبح من الصعب إدارته في الشبكات الكبيرة.&lt;/li&gt;
&lt;li&gt;لا يتكيف تلقائيًا مع جميع حالات تعطل المسارات.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: right;"&gt;التوجيه الديناميكي (Dynamic Routing)&lt;/h4&gt;
&lt;p&gt;في هذا الأسلوب، تستخدم الموجّهات بروتوكولات توجيه لتبادل المعلومات واختيار المسارات وتحديثها.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;المميزات:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;مناسب للشبكات الكبيرة والمتغيرة.&lt;/li&gt;
&lt;li&gt;يمكنه التكيف مع بعض تغييرات الشبكة والأعطال.&lt;/li&gt;
&lt;li&gt;يقلل الحاجة إلى إدارة جميع المسارات يدويًا.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;العيوب:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;يحتاج إلى فهم البروتوكول وإعداده بصورة صحيحة.&lt;/li&gt;
&lt;li&gt;قد يستهلك موارد إضافية.&lt;/li&gt;
&lt;li&gt;يتطلب الانتباه إلى أمن بروتوكولات التوجيه وسياساتها.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;في شبكة منزلية بسيطة، قد يكفي وجود مسار افتراضي واحد نحو مزود الخدمة.&lt;/p&gt;
&lt;p&gt;أما في مؤسسة كبيرة تمتلك فروعًا متعددة وروابط اتصال احتياطية، فقد يكون استخدام بروتوكول توجيه ديناميكي مناسبًا لتبادل المسارات والتعامل مع التغييرات.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;لماذا قد يتصل الجهاز بالراوتر دون أن يعمل الإنترنت؟&lt;/h3&gt;
&lt;p&gt;من المهم التمييز بين الاتصال بالشبكة المحلية والقدرة على الوصول إلى الإنترنت.&lt;/p&gt;
&lt;p&gt;قد يكون هاتفك متصلًا بشبكة Wi-Fi، لكنك لا تستطيع فتح المواقع الإلكترونية.&lt;/p&gt;
&lt;p&gt;من الأسباب المحتملة:&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;انقطاع خدمة مزود الإنترنت :&amp;nbsp;&lt;/b&gt;قد يعمل الراوتر بصورة طبيعية بينما تكون وصلة مزود الخدمة معطلة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;مشكلة في DNS :&amp;nbsp;&lt;/b&gt;قد تكون الشبكة قادرة على الوصول إلى عناوين IP، لكن أسماء النطاقات لا تُحل بصورة صحيحة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;إعدادات IP غير صحيحة :&amp;nbsp;&lt;/b&gt;قد يكون الجهاز قد حصل على عنوان IP أو بوابة افتراضية غير مناسبة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;مشكلة في كابل الاتصال أو منفذ WAN :&amp;nbsp;&lt;/b&gt;قد يكون الكابل غير مثبت جيدًا أو يوجد خلل في الاتصال بين الراوتر وجهاز المودم أو ONT.&lt;/li&gt;&lt;li&gt;&lt;b&gt;مشكلة في إعدادات الراوتر :&amp;nbsp;&lt;/b&gt;قد تمنع قواعد جدار الحماية أو إعدادات التوجيه أو المصادقة وصول البيانات إلى الإنترنت.&lt;/li&gt;&lt;li&gt;&lt;b&gt;مشكلة في ازدحام الشبكة أو ضعف الإشارة :&amp;nbsp;&lt;/b&gt;قد تؤدي كثرة الأجهزة أو ضعف إشارة Wi-Fi أو التداخل اللاسلكي إلى بطء الاتصال أو انقطاعه.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;





&lt;h4 style="text-align: right;"&gt;خطوات أولية للتشخيص&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;تحقق من اتصال الجهاز بشبكة Wi-Fi.&lt;/li&gt;
&lt;li&gt;افحص حالة مؤشرات الاتصال في الراوتر.&lt;/li&gt;
&lt;li&gt;نفّذ &lt;code&gt;ipconfig&lt;/code&gt; لمعرفة عنوان IP والبوابة الافتراضية.&lt;/li&gt;
&lt;li&gt;جرّب &lt;code&gt;ping&lt;/code&gt; على عنوان البوابة.&lt;/li&gt;
&lt;li&gt;اختبر الوصول إلى وجهة خارجية، مع مراعاة أن بعض الوجهات لا تستجيب لطلبات ICMP.&lt;/li&gt;
&lt;li&gt;افحص إعدادات DNS إذا كانت الاتصالات إلى عناوين IP تعمل، بينما تفشل أسماء المواقع.&lt;/li&gt;
&lt;li&gt;تحقق من حالة خدمة مزود الإنترنت إذا استمرت المشكلة.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;لا تعتمد على اختبار واحد فقط؛ فالتشخيص الصحيح يحتاج إلى مقارنة نتائج عدة اختبارات.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;هل الراوتر مسؤول عن سرعة الإنترنت؟&lt;/h3&gt;
&lt;p&gt;الراوتر يؤثر في تجربة الاتصال، لكنه ليس العامل الوحيد الذي يحدد سرعة الإنترنت.&lt;/p&gt;
&lt;p&gt;تتأثر السرعة بعدة عوامل، منها:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;سرعة الاشتراك لدى مزود الخدمة.&lt;/li&gt;
&lt;li&gt;نوع الاتصال المستخدم.&lt;/li&gt;
&lt;li&gt;قدرة الراوتر على معالجة حركة البيانات.&lt;/li&gt;
&lt;li&gt;سرعة منافذ Ethernet.&lt;/li&gt;
&lt;li&gt;معيار Wi-Fi المستخدم.&lt;/li&gt;
&lt;li&gt;قوة الإشارة اللاسلكية.&lt;/li&gt;
&lt;li&gt;التداخل من الشبكات والأجهزة المجاورة.&lt;/li&gt;
&lt;li&gt;عدد الأجهزة النشطة وحجم البيانات التي تنقلها.&lt;/li&gt;
&lt;li&gt;أداء الخادم الذي تتصل به.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;إذا كانت سرعة اتصالك من مزود الخدمة تبلغ 100 ميغابت في الثانية، لكن الراوتر أو أحد منافذه لا يستطيع التعامل مع السرعة المطلوبة، فقد تصبح قدرات الجهاز عاملًا يحد من الأداء.&lt;/p&gt;
&lt;p&gt;كذلك، لا تعني السرعة النظرية المعلنة لشبكة Wi-Fi أن المستخدم سيحصل على السرعة نفسها في جميع الظروف؛ إذ تتأثر السرعة الفعلية بالمسافة والتداخل وقدرات الأجهزة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما الفرق بين الراوتر ونقطة الوصول ومقوي الإشارة؟&lt;/h3&gt;
&lt;p&gt;توجد أجهزة أخرى تُستخدم لتحسين الاتصال، لكنها لا تؤدي جميعها وظيفة الراوتر.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الراوتر (Router) :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يربط الشبكات ويوجه حزم IP بينها.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;نقطة الوصول (Access Point) :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تسمح للأجهزة اللاسلكية بالاتصال بشبكة محلية موجودة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;مقوي أو موسع إشارة Wi-Fi (Wi-Fi Extender) :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يهدف إلى توسيع التغطية اللاسلكية، وقد يعيد بث الإشارة أو يستخدم أسلوبًا آخر للاتصال بالشبكة الأساسية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;نظام الشبكة المتداخلة (Mesh Wi-Fi) :&amp;nbsp;&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يتكون من عدة وحدات تعمل معًا لتوفير تغطية لاسلكية أوسع، وفقًا لتصميم النظام.&lt;/p&gt;
&lt;p&gt;قد تتضمن بعض أنظمة Mesh وظائف توجيه أيضًا، بينما تعمل وحدات أخرى كنقاط وصول أو وحدات تمديد بحسب طريقة إعدادها.&lt;/p&gt;
&lt;p&gt;لذلك، من المهم معرفة وظيفة الجهاز الفعلية بدلًا من الاعتماد على اسمه التجاري فقط.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;تطبيق عملي لفهم عمل الراوتر&lt;/h3&gt;
&lt;p&gt;لننفذ تمرينًا بسيطًا يساعدك على ربط المفاهيم النظرية بالتطبيق العملي.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;متطلبات التمرين&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;حاسوب يعمل بنظام Windows.&lt;/li&gt;
&lt;li&gt;اتصال بشبكة منزلية أو شبكة محلية يُسمح لك باستخدامها.&lt;/li&gt;
&lt;li&gt;الوصول إلى موجه الأوامر CMD.&lt;/li&gt;
&lt;/ul&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الأولى: معرفة عنوان IP&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;افتح CMD واكتب:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;ipconfig&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;سجّل عنوان IPv4 الخاص بمحول الشبكة النشط.&lt;/p&gt;
&lt;p&gt;مثال:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.10&lt;/code&gt;&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الثانية: معرفة البوابة الافتراضية&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;ابحث عن السطر:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;Default Gateway&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;قد يظهر مثلًا:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الثالثة: اختبار الاتصال بالراوتر&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;اكتب:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;ping 192.168.1.1&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;إذا كان عنوان البوابة لديك مختلفًا، فاستخدم العنوان الصحيح.&lt;/p&gt;
&lt;p&gt;راقب ما إذا كانت هناك ردود من الجهاز.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الرابعة: استكشاف المسار&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;اكتب:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;tracert 8.8.8.8&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;لاحظ أن المسار قد يتضمن عدة قفزات، وقد لا تظهر معلومات جميع الموجّهات بسبب سياسات الاستجابة أو قيود الشبكة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الخامسة: عرض جدول التوجيه&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;اكتب:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;route print&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;حاول العثور على المسار الافتراضي في جدول IPv4، والذي قد يظهر بالشكل:&lt;/p&gt;
&lt;p dir="ltr" style="text-align: left;"&gt;&lt;code&gt;0.0.0.0          0.0.0.0&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;وقد يكون عنوان البوابة في المثال هو &lt;code&gt;192.168.1.1&lt;/code&gt;، لكن النتيجة تعتمد على إعدادات جهازك.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;أسئلة التمرين&lt;/b&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;ما عنوان IPv4 الذي حصل عليه حاسوبك؟&lt;/li&gt;
&lt;li&gt;ما عنوان البوابة الافتراضية؟&lt;/li&gt;
&lt;li&gt;هل استطعت الوصول إلى البوابة باستخدام &lt;code&gt;ping&lt;/code&gt;؟&lt;/li&gt;
&lt;li&gt;لماذا يحتاج حاسوبك إلى البوابة الافتراضية عند الاتصال بوجهة خارج شبكته المحلية؟&lt;/li&gt;
&lt;li&gt;ما الفرق بين عنوان الحاسوب وعنوان الراوتر المحلي؟&lt;/li&gt;
&lt;li&gt;لماذا قد تمر البيانات عبر عدة موجّهات قبل الوصول إلى خادم بعيد؟&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;ملاحظة للخصوصية:&lt;/strong&gt; لا تنشر عنوان IP العام أو تفاصيل شبكتك الكاملة في التعليقات. يمكنك الاكتفاء بكتابة «تم التطبيق» بعد إكمال التمرين.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/5705586405868259931/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/router-how-data-moves-between-networks.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5705586405868259931" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5705586405868259931" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/router-how-data-moves-between-networks.html" rel="alternate" title="دليل شامل للمبتدئين عن الراوتر وكيفية نقل البيانات بين الشبكات" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmlwWs8b4KKIBxxXowfyPCxc3yw69mwOXqwcXD5EeNda80DIMFUl74ug65Cm_F05CBixF6q0RIucf4RId1qZOeUSwvG0Lpq3bu88BQkNQOWMp_erZjOA0xayG3H2f7qkaAWWUGqEI5oxHynzU9_W_4ebtTfO8MXCdOWxPBu5lDGjkhSpuw4MHL1FkO9AA9/s72-c/imageedit_1_2639328084.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-5924405159787639753</id><published>2026-10-13T09:59:17.971+03:00</published><updated>2026-10-13T09:59:17.971+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="توعية"/><title type="text">ماهو هجوم تجانس الأحرف Homograph Attack وكيف يكون</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUcuOfd-9XGNZQUVNYM71oQidASPpP0VcSJKdS4Jmq_ShgGDP2L7pxuCXck0DHsx9lt2CclFQ6Ydm384LqrQoY6IZwP_VNa1sfxTwt_mFizmgWtJoLKzBceywTq8zrLEJfsxYz4K1Qj77ihy3CHAs2VrzZq8gwJKtiHkVsYX1Aw4zMuLaPfoh8-ish5_cG/s640/imageedit_1_8496087119.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="هجوم تجانس الأحرف (Homograph Attack)" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUcuOfd-9XGNZQUVNYM71oQidASPpP0VcSJKdS4Jmq_ShgGDP2L7pxuCXck0DHsx9lt2CclFQ6Ydm384LqrQoY6IZwP_VNa1sfxTwt_mFizmgWtJoLKzBceywTq8zrLEJfsxYz4K1Qj77ihy3CHAs2VrzZq8gwJKtiHkVsYX1Aw4zMuLaPfoh8-ish5_cG/s1600/imageedit_1_8496087119.webp" title="هجوم تجانس الأحرف (Homograph Attack)" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;هجوم تجانس الأحرف كيف تخدعك الروابط المزيفة دون أن تلاحظ؟&lt;/h3&gt;
&lt;p&gt;في عالم الأمن السيبراني، لا تحتاج جميع الهجمات الإلكترونية إلى اختراق الأنظمة المعقدة أو استغلال الثغرات البرمجية. فقد يعتمد بعضها على خداع العين البشرية واستغلال الطريقة التي نقرأ بها النصوص وعناوين المواقع الإلكترونية.&lt;/p&gt;
&lt;p&gt;تخيّل أنك تلقيت رسالة تحتوي على رابط يبدو أنه تابع لموقع مشهور، مثل موقع مصرفي أو منصة تواصل اجتماعي. تفحص الرابط سريعًا، فتجده مألوفًا، وتضغط عليه دون تردد. لكنك في الحقيقة قد تكون انتقلت إلى موقع مزيف صُمم لسرقة كلمة المرور أو معلوماتك الشخصية.&lt;/p&gt;
&lt;p&gt;كيف يحدث ذلك رغم أنك تحققت من اسم الموقع؟&lt;/p&gt;
&lt;p&gt;الإجابة قد تكون &lt;strong&gt;هجوم تجانس الأحرف (Homograph Attack)&lt;/strong&gt;، وهو أسلوب من أساليب الهجمات السيبرانية يعتمد على استغلال التشابه البصري بين الأحرف، خصوصًا الأحرف القادمة من أنظمة الكتابة المختلفة، لإنشاء أسماء نطاقات تبدو وكأنها أصلية، بينما تشير إلى مواقع أخرى.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما هو هجوم تجانس الأحرف (Homograph Attack)؟&lt;/h3&gt;
&lt;p&gt;هجوم تجانس الأحرف هو أسلوب خداع رقمي يستغل التشابه في الشكل بين حرفين أو أكثر لتمرير اسم نطاق أو نص مزيف على أنه اسم حقيقي.&lt;/p&gt;
&lt;p&gt;يُعرف هذا النوع من الهجمات أيضًا باسم هجوم النطاقات المتشابهة بصريًا (Homograph Domain Attack)، ويُستخدم كثيرًا ضمن حملات التصيد الإلكتروني (Phishing).&lt;/p&gt;
&lt;p&gt;تعتمد الفكرة على أن بعض الأحرف تبدو متطابقة أو متقاربة للغاية، رغم أنها تختلف في قيمتها الرقمية وهويتها ضمن معيار Unicode.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، يوجد اختلاف بين الحرف اللاتيني &lt;code&gt;a&lt;/code&gt; والحرف السيرِيلي &lt;code&gt;а&lt;/code&gt;، رغم أن شكلهما قد يبدو متطابقًا في بعض الخطوط:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;الحرف الأول: &lt;code&gt;a&lt;/code&gt; — حرف لاتيني صغير.&lt;/li&gt;
&lt;li&gt;الحرف الثاني: &lt;code&gt;а&lt;/code&gt; — حرف سيرِيلي صغير.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;قد لا يلاحظ المستخدم الفرق عند النظر إلى الأحرف بالعين المجردة، خصوصًا على شاشة الهاتف أو عند قراءة الرابط بسرعة.&lt;/p&gt;
&lt;p&gt;لكن الحاسوب يتعامل معهما بوصفهما حرفين مختلفين.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;ملاحظة علمية:&lt;/strong&gt; يُعد Unicode معيارًا لترميز الأحرف والرموز المستخدمة في أنظمة الكتابة المختلفة، وليس جميع الأحرف المتشابهة متطابقة في قيمها الرقمية.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;كيف يعمل هجوم تجانس الأحرف؟&lt;/h3&gt;
&lt;p&gt;لفهم هذا الهجوم، يجب أولًا معرفة أن أسماء النطاقات ليست مجرد كلمات تظهر في شريط العنوان، بل تخضع لقواعد تقنية تحدد كيفية تمثيلها ومعالجتها بواسطة أنظمة أسماء النطاقات (DNS).&lt;/p&gt;
&lt;p&gt;تحدث الهجمات عادة عبر مجموعة من الخطوات.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. اختيار اسم نطاق يشبه الموقع الأصلي&lt;/h4&gt;
&lt;p&gt;يبدأ المهاجم باختيار اسم نطاق يشبه اسم موقع معروف، مثل موقع مصرف أو منصة اجتماعية أو خدمة بريد إلكتروني.&lt;/p&gt;
&lt;p&gt;وقد يستبدل حرفًا لاتينيًا بحرف من نظام كتابة آخر يشبهه بصريًا.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، قد يبدو حرف &lt;code&gt;a&lt;/code&gt; اللاتيني مطابقًا لحرف &lt;code&gt;а&lt;/code&gt; السيرِيلي في بعض الخطوط.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. تسجيل النطاق المزيف&lt;/h4&gt;
&lt;p&gt;قد يسجل المهاجم اسم نطاق يحتوي على أحرف من أنظمة كتابة مختلفة، إذا سمحت قواعد تسجيل النطاقات بذلك.&lt;/p&gt;
&lt;p&gt;تُعرف هذه النطاقات باسم أسماء النطاقات الدولية (Internationalized Domain Names - IDNs)، وهي تقنية تسمح باستخدام أحرف من لغات وأنظمة كتابة متعددة في أسماء النطاقات.&lt;/p&gt;
&lt;p&gt;من المهم توضيح أن أسماء النطاقات الدولية ليست خطيرة بطبيعتها؛ فهي تقنية مشروعة ومفيدة، لكن المهاجمين قد يستغلونها في إنشاء أسماء مضللة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. إنشاء موقع يشبه الموقع الأصلي&lt;/h4&gt;
&lt;p&gt;بعد تجهيز النطاق، قد ينشئ المهاجم صفحة تحاكي تصميم موقع حقيقي، بما في ذلك الألوان والشعار وحقول تسجيل الدخول.&lt;/p&gt;
&lt;p&gt;وقد يستخدم الموقع المزيف لإقناع الزائر بإدخال بيانات حساسة، مثل:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;اسم المستخدم وكلمة المرور.&lt;/li&gt;
&lt;li&gt;بيانات الحسابات المصرفية.&lt;/li&gt;
&lt;li&gt;رموز التحقق المؤقتة.&lt;/li&gt;
&lt;li&gt;المعلومات الشخصية.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: right;"&gt;4. نشر الرابط عبر رسائل التصيد&lt;/h4&gt;
&lt;p&gt;يرسل المهاجم الرابط عبر البريد الإلكتروني أو الرسائل النصية أو تطبيقات التواصل الاجتماعي.&lt;/p&gt;
&lt;p&gt;وقد يرفق به رسالة تدّعي ضرورة تحديث الحساب أو تأكيد الهوية أو معالجة مشكلة أمنية عاجلة.&lt;/p&gt;
&lt;p&gt;عندما يثق المستخدم في شكل الرابط، فقد يدخل بياناته في الصفحة المزيفة دون أن يدرك أنه يتعامل مع جهة غير موثوقة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;ما الفرق بين الحرف الأصلي والحرف المتشابه؟&lt;/h4&gt;
&lt;p&gt;من أهم الأسباب التي تجعل هذا الهجوم فعالًا أن العين البشرية لا تميّز دائمًا بين الأحرف المتشابهة.&lt;/p&gt;
&lt;p&gt;انظر إلى المثال التالي:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;الحرف&lt;/th&gt;
&lt;th&gt;نظام الكتابة&lt;/th&gt;
&lt;th&gt;الاسم&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;a&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;اللاتينية&lt;/td&gt;
&lt;td&gt;Latin Small Letter A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;а&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;السيريلية&lt;/td&gt;
&lt;td&gt;Cyrillic Small Letter A&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;o&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;اللاتينية&lt;/td&gt;
&lt;td&gt;Latin Small Letter O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;о&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;السيريلية&lt;/td&gt;
&lt;td&gt;Cyrillic Small Letter O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;p&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;اللاتينية&lt;/td&gt;
&lt;td&gt;Latin Small Letter P&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;р&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;السيريلية&lt;/td&gt;
&lt;td&gt;Cyrillic Small Letter Er&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;قد تبدو هذه الأحرف متطابقة تقريبًا في بعض الخطوط، لكنها ليست الحرف نفسه.&lt;/p&gt;
&lt;p&gt;وتعتمد درجة التشابه على نوع الخط وحجم النص وطريقة عرضه.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;لماذا يمثل ذلك مشكلة أمنية؟&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;لأن المستخدم غالبًا ما يتعرف على المواقع من خلال شكل الاسم، وليس من خلال فحص الهوية التقنية لكل حرف.&lt;/p&gt;
&lt;p&gt;وبالتالي، يمكن أن يصبح التشابه البصري وسيلة لتضليل المستخدم، خصوصًا عندما يكون الرابط طويلًا أو معروضًا بصورة مختصرة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما علاقة Unicode وPunycode بهجوم تجانس الأحرف؟&lt;/h3&gt;
&lt;p&gt;لفهم الجانب التقني لهذا الهجوم، يجب التعرف على تقنيتين مهمتين: Unicode وPunycode.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. ما هو Unicode؟&lt;/h4&gt;
&lt;p&gt;Unicode معيار يهدف إلى تمثيل الأحرف والرموز من مختلف لغات العالم بطريقة موحدة.&lt;/p&gt;
&lt;p&gt;فهو يسمح للحاسوب بالتعامل مع الأحرف العربية والإنجليزية والسيريلية والصينية وغيرها.&lt;/p&gt;
&lt;p&gt;لكن وجود أحرف متشابهة بصريًا ضمن أنظمة كتابة مختلفة قد يخلق فرصًا للخداع عند استخدامها في أسماء النطاقات.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. ما هو Punycode؟&lt;/h4&gt;
&lt;p&gt;Punycode هو أسلوب لترميز أسماء النطاقات التي تحتوي على أحرف غير لاتينية أو أحرف تتجاوز مجموعة الأحرف المسموح بها في تمثيل DNS التقليدي.&lt;/p&gt;
&lt;p&gt;فعلى سبيل المثال، قد يظهر اسم نطاق دولي في المتصفح بصيغته المقروءة، بينما يُمثَّل داخليًا بصيغة تبدأ عادةً بالبادئة &lt;code&gt;xn--&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;تعتمد طريقة العرض على المتصفح وسياساته الأمنية، ولذلك لا تظهر جميع أسماء النطاقات الدولية بالشكل نفسه في كل المتصفحات.&lt;/p&gt;
&lt;p&gt;يمكن أن يساعد عرض اسم النطاق بصيغة Punycode في كشف بعض النطاقات المضللة، لكنه ليس حلًا كاملًا؛ فليس كل نطاق يبدأ بـ &lt;code&gt;xn--&lt;/code&gt; خبيثًا، لأن كثيرًا من النطاقات الدولية مشروعة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. هل يستطيع المتصفح اكتشاف النطاقات المزيفة؟&lt;/h4&gt;
&lt;p&gt;تستخدم المتصفحات الحديثة مجموعة من السياسات والضوابط لتقليل مخاطر أسماء النطاقات المتشابهة.&lt;/p&gt;
&lt;p&gt;وقد تعتمد هذه السياسات على عوامل مثل:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;الأحرف المستخدمة في اسم النطاق.&lt;/li&gt;
&lt;li&gt;خلط أنظمة الكتابة المختلفة.&lt;/li&gt;
&lt;li&gt;درجة التشابه مع أسماء نطاقات أخرى.&lt;/li&gt;
&lt;li&gt;قواعد عرض أسماء النطاقات الدولية.&lt;/li&gt;
&lt;li&gt;سمعة الموقع وإشارات الأمان المتاحة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;لكن هذه الحماية تختلف بين المتصفحات وإصداراتها، ولا تضمن اكتشاف كل رابط مضلل.&lt;/p&gt;
&lt;p&gt;لذلك، لا ينبغي الاعتماد على المتصفح وحده لتحديد ما إذا كان الموقع آمنًا.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما الفرق بين هجوم تجانس الأحرف وهجمات التصيد الأخرى؟&lt;/h3&gt;
&lt;p&gt;توجد عدة أساليب لإنشاء روابط مضللة، وقد تتشابه في أهدافها، لكنها تختلف في طريقة التنفيذ.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. هجوم تجانس الأحرف (Homograph Attack)&lt;/h4&gt;
&lt;p&gt;يعتمد على التشابه البصري بين الأحرف، بما في ذلك الأحرف المأخوذة من أنظمة كتابة مختلفة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. هجوم Typosquatting&lt;/h4&gt;
&lt;p&gt;يعتمد على تسجيل أسماء نطاقات تحتوي على أخطاء إملائية شائعة أو تغييرات بسيطة في كتابة اسم الموقع.&lt;/p&gt;
&lt;p&gt;قد يستهدف المهاجم المستخدم الذي يكتب اسم الموقع بطريقة خاطئة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. هجوم Subdomain Spoofing&lt;/h4&gt;
&lt;p&gt;يعتمد على استغلال سوء فهم المستخدم لبنية اسم النطاق، مثل وضع اسم علامة تجارية في جزء فرعي من نطاق يملكه المهاجم.&lt;/p&gt;
&lt;p&gt;فعلى سبيل المثال، قد يحتوي الرابط على اسم شركة معروف قبل اسم نطاق مختلف، فيظن المستخدم أن الشركة هي المالكة للموقع.&lt;/p&gt;
&lt;p&gt;القاعدة الأساسية هنا هي أن &lt;strong&gt;اسم النطاق الفعلي يُقرأ من اليمين إلى اليسار حتى نحدد النطاق المسجل، مع مراعاة قواعد أسماء النطاقات العامة والفرعية&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;4. التصيد باستخدام الروابط المختصرة&lt;/h4&gt;
&lt;p&gt;يستخدم المهاجم رابطًا مختصرًا يخفي الوجهة الحقيقية، بحيث لا يستطيع المستخدم معرفة اسم النطاق المستهدف بمجرد النظر إلى الرابط المختصر.&lt;/p&gt;
&lt;p&gt;قد تُستخدم هذه الطريقة في هجمات التصيد، لكنها ليست خبيثة في حد ذاتها.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما مخاطر هجوم تجانس الأحرف؟&lt;/h3&gt;
&lt;p&gt;قد يؤدي هذا النوع من الهجمات إلى مجموعة من المخاطر الأمنية، وفقًا لطبيعة الموقع المزيف والبيانات التي يحاول جمعها.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;سرقة بيانات تسجيل الدخول &lt;/b&gt;: قد يدخل المستخدم كلمة المرور في صفحة مزيفة يعتقد أنها تابعة لخدمة حقيقية.&lt;/li&gt;&lt;li&gt;&lt;b&gt;الاستيلاء على الحسابات &lt;/b&gt;: إذا حصل المهاجم على بيانات تسجيل الدخول أو رموز التحقق، فقد يحاول استخدامها للوصول إلى حسابات الضحية. وقد تساعد المصادقة متعددة العوامل على تقليل بعض المخاطر، لكنها لا تمنع جميع أساليب التصيد، خصوصًا الهجمات التي تستهدف جلسات تسجيل الدخول أو رموز المصادقة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;الاحتيال المالي&lt;/b&gt; : قد تُستخدم المواقع المزيفة لخداع المستخدمين ودفعهم إلى إدخال بيانات مالية أو تنفيذ تحويلات إلى جهات غير موثوقة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;نشر البرمجيات الخبيثة&lt;/b&gt; : قد يحاول الموقع المزيف إقناع الزائر بتنزيل ملف ضار أو تثبيت تطبيق غير موثوق.ومع ذلك، فإن مجرد زيارة نطاق مشابه بصريًا لا تعني بالضرورة أن الجهاز قد أُصيب ببرمجية خبيثة؛ إذ يعتمد ذلك على سلوك الموقع والتفاعلات التي حدثت.&lt;/li&gt;&lt;li&gt;&lt;b&gt;الإضرار بسمعة المؤسسات&lt;/b&gt; : يمكن استخدام النطاقات المتشابهة بصريًا لانتحال هوية الشركات والمؤسسات، مما قد يؤدي إلى خسائر مالية وإضعاف ثقة العملاء.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;




&lt;h3 style="text-align: right;"&gt;كيف تكتشف هجوم تجانس الأحرف؟&lt;/h3&gt;
&lt;p&gt;يمكن اتباع مجموعة من الخطوات العملية لتقليل احتمال الوقوع ضحية لهذا النوع من الهجمات.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;1. افحص اسم النطاق بدقة&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;لا تعتمد على المظهر العام للرابط وحده.&lt;/p&gt;
&lt;p&gt;تحقق من اسم النطاق الذي يشير إليه الرابط، وانتبه إلى الأحرف التي قد تكون متشابهة بصريًا.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، قارن بين الحرفين التاليين:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;a&lt;/code&gt; و&lt;code&gt;а&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;قد يصعب التفريق بينهما بصريًا، لكنهما مختلفان في الترميز.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;2. ادخل إلى الموقع من مصدر موثوق&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;إذا وصلتك رسالة تدّعي وجود مشكلة في حسابك المصرفي أو حساب التواصل الاجتماعي، فلا تضغط على الرابط مباشرة.&lt;/p&gt;
&lt;p&gt;بدلًا من ذلك، افتح التطبيق الرسمي أو اكتب عنوان الموقع الذي تعرفه بنفسك، أو استخدم إشارة مرجعية سبق أن حفظتها بعد التحقق منها.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;3. لا تثق بوجود HTTPS وحده&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يشير HTTPS إلى استخدام اتصال مشفر بين المتصفح والموقع، لكنه لا يثبت أن الموقع تابع لجهة موثوقة.&lt;/p&gt;
&lt;p&gt;فقد تستخدم المواقع المزيفة شهادات TLS صحيحة وتوفر اتصالًا مشفرًا أيضًا.&lt;/p&gt;
&lt;p&gt;لذلك، يجب التحقق من اسم النطاق وهوية الجهة التي تتعامل معها، وليس الاكتفاء بوجود رمز القفل.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;4. انتبه للرسائل المستعجلة&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;إذا طلبت منك رسالة تسجيل الدخول فورًا أو هددتك بإغلاق الحساب خلال دقائق، فتحقق من صحتها عبر القنوات الرسمية.&lt;/p&gt;
&lt;p&gt;تُستخدم الاستعجالية والتهديد أحيانًا للضغط على المستخدم وتقليل الوقت الذي يمنحه لفحص الرابط.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;5. استخدم مدير كلمات المرور&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تساعد بعض برامج إدارة كلمات المرور في تقليل أخطاء تسجيل الدخول؛ إذ ترتبط بيانات الاعتماد عادةً بالنطاق الذي حُفظت له.&lt;/p&gt;
&lt;p&gt;إذا لم يقترح مدير كلمات المرور بيانات الدخول المعتادة، فقد يكون ذلك مؤشرًا يستحق التحقق، لكنه ليس دليلًا قاطعًا على أن الموقع مزيف.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;6. حدّث المتصفح ونظام التشغيل&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تساعد التحديثات الأمنية على الاستفادة من التحسينات المتعلقة بعرض أسماء النطاقات واكتشاف المواقع الضارة.&lt;/p&gt;
&lt;p&gt;احرص على تحديث المتصفح ونظام التشغيل باستمرار، وتجنب تثبيت الإضافات من مصادر غير موثوقة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ماذا تفعل إذا فتحت رابطًا مزيفًا؟&lt;/h3&gt;
&lt;p&gt;إذا اكتشفت أنك زرت موقعًا قد يكون مزيفًا، فلا داعي لافتراض أن بياناتك سُرقت تلقائيًا. اتخذ الإجراءات المناسبة وفقًا لما حدث.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;إذا فتحت الرابط فقط:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;أغلق الصفحة إذا كانت مشبوهة.&lt;/li&gt;
&lt;li&gt;لا تنزّل الملفات ولا تسمح بالإشعارات أو الأذونات غير الضرورية.&lt;/li&gt;
&lt;li&gt;حدّث المتصفح ونظام التشغيل إذا لم يكونا محدثين.&lt;/li&gt;
&lt;li&gt;إذا نُزّل ملف أو ظهرت مؤشرات غير طبيعية، افحص الجهاز بأداة حماية موثوقة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;إذا أدخلت كلمة المرور:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;غيّرها فورًا من الموقع أو التطبيق الرسمي.&lt;/li&gt;
&lt;li&gt;إذا كنت تستخدم كلمة المرور نفسها في مواقع أخرى، فغيّرها هناك أيضًا.&lt;/li&gt;
&lt;li&gt;سجّل الخروج من الجلسات الأخرى إذا كانت الخدمة تتيح ذلك.&lt;/li&gt;
&lt;li&gt;فعّل المصادقة متعددة العوامل.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;إذا أدخلت بيانات مصرفية أو مالية:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;اتصل بالمصرف عبر رقم أو قناة رسمية.&lt;/li&gt;
&lt;li&gt;اطلب إيقاف المعاملات أو البطاقة عند الحاجة.&lt;/li&gt;
&lt;li&gt;راجع سجل المعاملات وأبلغ عن أي عملية مشبوهة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;إذا أدخلت رمز تحقق مؤقتًا:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;تعامل مع الأمر باعتباره احتمالًا لوصول المهاجم إلى حسابك.&lt;/li&gt;
&lt;li&gt;أمّن الحساب فورًا، وراجع الجلسات والأجهزة المسجلة.&lt;/li&gt;
&lt;li&gt;تواصل مع مزود الخدمة إذا فقدت القدرة على الدخول.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style="text-align: right;"&gt;كيف يمكن للمطورين ومسؤولي الأمن السيبراني الحد من الهجوم؟&lt;/h3&gt;
&lt;p&gt;لا تقع مسؤولية مواجهة هجمات تجانس الأحرف على المستخدم وحده؛ إذ يمكن للمطورين ومسؤولي الأنظمة تطبيق مجموعة من التدابير الوقائية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;مراقبة النطاقات المتشابهة :&amp;nbsp;&lt;/b&gt;يمكن للمؤسسات مراقبة أسماء النطاقات الجديدة التي تشبه علاماتها التجارية، والتحقق من النطاقات المشتبه بها، والإبلاغ عنها للجهات المختصة عند الحاجة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;تطبيق سياسات أمنية مناسبة :&amp;nbsp;&lt;/b&gt;ينبغي لمطوري المتصفحات والتطبيقات استخدام آليات مناسبة للتعامل مع أسماء النطاقات الدولية، بما في ذلك السياسات التي تحدد متى يُعرض اسم النطاق بصيغته المقروءة ومتى يُعرض بترميز Punycode.&lt;/li&gt;&lt;li&gt;&lt;b&gt;استخدام المصادقة متعددة العوامل :&amp;nbsp;&lt;/b&gt;تساعد المصادقة متعددة العوامل على تقليل الاعتماد على كلمة المرور وحدها، رغم أنها لا تمنع جميع هجمات التصيد. وتوفر مفاتيح الأمان وتقنيات المصادقة المقاومة للتصيد، مثل WebAuthn وPasskeys، حماية أقوى ضد بعض الهجمات التي تحاول سرقة بيانات تسجيل الدخول.&lt;/li&gt;&lt;li&gt;&lt;b&gt;تطبيق سياسات حماية البريد الإلكتروني :&amp;nbsp;&lt;/b&gt;يمكن للمؤسسات استخدام تقنيات مثل SPF وDKIM وDMARC للمساعدة في الحد من انتحال نطاقات البريد الإلكتروني. لكن يجب التنبيه إلى أن هذه التقنيات لا تمنع وحدها تسجيل نطاق مشابه بصريًا أو إنشاء موقع تصيد مستقل.&lt;/li&gt;&lt;li&gt;&lt;b&gt;التوعية الأمنية :&amp;nbsp;&lt;/b&gt;تدريب الموظفين والمستخدمين على فحص الروابط والتعرف على أساليب التصيد يقلل من فرص نجاح الهجمات، خصوصًا عند اقتران التدريب بإجراءات تقنية واضحة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;




&lt;h3 style="text-align: right;"&gt;مثال تعليمي آمن لفهم هجوم تجانس الأحرف&lt;/h3&gt;
&lt;p&gt;يمكنك تجربة الفرق بين الحرفين التاليين مباشرة في محرر نصوص أو بيئة برمجية:&lt;/p&gt;
&lt;p&gt;الحرف الأول: &lt;code&gt;a&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;الحرف الثاني: &lt;code&gt;а&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;على الرغم من التشابه البصري، فإن الأول حرف لاتيني، والثاني حرف سيرِيلي.&lt;/p&gt;
&lt;p&gt;وفي Python، يمكن فحص نقطة الترميز لكل حرف باستخدام الدالة &lt;code&gt;ord()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;latin_a = "a"
cyrillic_a = "а"

print("Latin a:", hex(ord(latin_a)))
print("Cyrillic a:", hex(ord(cyrillic_a)))

print("Are they identical?", latin_a == cyrillic_a)
&lt;/pre&gt;
&lt;p&gt;ستظهر النتيجة بالشكل التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Latin a: 0x61
Cyrillic a: 0x430
Are they identical? False
&lt;/pre&gt;
&lt;p&gt;يوضح المثال أن الحرفين مختلفان من الناحية الرقمية، حتى عندما يصعب التمييز بينهما بالعين.&lt;/p&gt;
&lt;p&gt;يمكن استخدام هذا النوع من الاختبارات في تعليم الأمن السيبراني، وفهم Unicode، وتطوير أدوات فحص النصوص وأسماء النطاقات.&lt;/p&gt;
&lt;p&gt;لكن هذا الاختبار البسيط لا يكفي وحده لاكتشاف جميع النطاقات المشبوهة؛ إذ يتطلب التقييم الأمني مراعاة قواعد أسماء النطاقات الدولية وسياسات المتصفحات وسياق الاستخدام.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;هل يمكن أن تحدث هذه الهجمات باللغة العربية؟&lt;/h3&gt;
&lt;p&gt;نعم، يمكن أن تظهر مشكلات التشابه البصري في سياقات تتضمن العربية وغيرها من أنظمة الكتابة.&lt;/p&gt;
&lt;p&gt;لكن ليس كل تشابه بين الأحرف العربية واللاتينية هجومًا، كما أن دعم أسماء النطاقات العربية لا يعني أنها غير آمنة بطبيعتها.&lt;/p&gt;
&lt;p&gt;تختلف مخاطر التشابه وفقًا للأحرف المستخدمة والخطوط المعروضة وسياسات معالجة أسماء النطاقات.&lt;/p&gt;
&lt;p&gt;كذلك يجب التمييز بين هجوم تجانس الأحرف، الذي يستغل التشابه البصري، وهجمات أخرى تعتمد على اتجاه النص أو طريقة عرض الأحرف المختلطة.&lt;/p&gt;
&lt;p&gt;وبالنسبة للمستخدم العربي، تظل النصيحة الأهم هي التحقق من النطاق الفعلي وعدم الاعتماد على الشكل وحده، خصوصًا عند التعامل مع الحسابات المالية والخدمات الحساسة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;أهم النصائح لتجنب هجوم تجانس الأحرف&lt;/h3&gt;
&lt;p&gt;لزيادة مستوى الأمان أثناء تصفح الإنترنت، اتبع الإرشادات التالية:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;لا تضغط على الروابط الحساسة الواردة من مصادر مجهولة.&lt;/li&gt;
&lt;li&gt;تحقق من اسم النطاق قبل إدخال بيانات تسجيل الدخول.&lt;/li&gt;
&lt;li&gt;استخدم التطبيقات الرسمية عند الوصول إلى الحسابات المالية.&lt;/li&gt;
&lt;li&gt;لا تعتبر HTTPS دليلًا كافيًا على موثوقية الموقع.&lt;/li&gt;
&lt;li&gt;استخدم مدير كلمات مرور موثوقًا.&lt;/li&gt;
&lt;li&gt;فعّل المصادقة متعددة العوامل.&lt;/li&gt;
&lt;li&gt;حدّث المتصفح ونظام التشغيل باستمرار.&lt;/li&gt;
&lt;li&gt;لا تثق في الرسائل التي تطلب منك اتخاذ إجراء عاجل دون تحقق.&lt;/li&gt;
&lt;li&gt;تجنب تنزيل الملفات من المواقع المشبوهة.&lt;/li&gt;
&lt;li&gt;أبلغ عن النطاقات المزيفة للجهة المنتحلة هويتها أو لمزود الخدمة المناسب.&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;يُظهر هجوم تجانس الأحرف أن المخاطر السيبرانية لا تعتمد دائمًا على تعقيد البرمجيات أو قوة الاختراق؛ فقد تبدأ أحيانًا من اختلاف صغير في حرف واحد لا تلاحظه العين البشرية.&lt;/p&gt;
&lt;p&gt;وتساعد معرفة الفرق بين الأحرف المتشابهة، وفهم آلية عمل أسماء النطاقات الدولية، والتحقق من الروابط قبل استخدامها، على تقليل مخاطر التصيد وسرقة الحسابات.&lt;/p&gt;
&lt;p&gt;ومع تطور تقنيات المتصفحات وأدوات الحماية، تظل الممارسات الأمنية الواعية جزءًا أساسيًا من حماية الهوية الرقمية والبيانات الشخصية.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;تذكّر: قد يبدو الرابط صحيحًا، لكن التشابه في الشكل لا يعني التطابق في الهوية.&lt;/strong&gt;&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/5924405159787639753/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/homograph-attack-generator.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5924405159787639753" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5924405159787639753" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/homograph-attack-generator.html" rel="alternate" title="ماهو هجوم تجانس الأحرف Homograph Attack وكيف يكون" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgUcuOfd-9XGNZQUVNYM71oQidASPpP0VcSJKdS4Jmq_ShgGDP2L7pxuCXck0DHsx9lt2CclFQ6Ydm384LqrQoY6IZwP_VNa1sfxTwt_mFizmgWtJoLKzBceywTq8zrLEJfsxYz4K1Qj77ihy3CHAs2VrzZq8gwJKtiHkVsYX1Aw4zMuLaPfoh8-ish5_cG/s72-c/imageedit_1_8496087119.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-576958100236516656</id><published>2026-10-12T11:11:50.784+03:00</published><updated>2026-10-12T11:11:50.784+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">كيفية تحويل الفيديو إلى نص مكتوب باستخدام الذكاء الاصطناعي</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOqmOB0zUDRycuvdDCIDXucS8bz2pmk9V6Tcx_CbqDU77FcoJl3bGzmYaEMP4U8Ew38aU8jqdmHmdE1NBoK73e-SxTM_Fy543Ulu7z5U5p8lXNGHOaxe5Ri5fI7jf7lOy1W_12P_ZEidhSOds6x0E8ocPTNBzhXI0l2BS1D7Qj_ewc0s1gQu80NCTV6fZP/s640/imageedit_1_7505088793.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="كيفية تحويل الفيديو إلى نص مكتوب باستخدام الذكاء الاصطناعي" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOqmOB0zUDRycuvdDCIDXucS8bz2pmk9V6Tcx_CbqDU77FcoJl3bGzmYaEMP4U8Ew38aU8jqdmHmdE1NBoK73e-SxTM_Fy543Ulu7z5U5p8lXNGHOaxe5Ri5fI7jf7lOy1W_12P_ZEidhSOds6x0E8ocPTNBzhXI0l2BS1D7Qj_ewc0s1gQu80NCTV6fZP/s1600/imageedit_1_7505088793.webp" title="كيفية تحويل الفيديو إلى نص مكتوب باستخدام الذكاء الاصطناعي" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;كيفية تحويل الفيديو إلى نص مكتوب باستخدام الذكاء الاصطناعي&lt;/h3&gt;
&lt;p&gt;أصبح تحويل الفيديو إلى نص مكتوب من أبرز الاستخدامات العملية لتقنيات الذكاء الاصطناعي، إذ يمكن للمستخدمين استخراج الكلام من مقاطع الفيديو والتسجيلات الصوتية وتحويله إلى نصوص قابلة للتحرير وإعادة النشر. وتساعد هذه التقنية على توفير الوقت والجهد، خاصةً للصحفيين والطلاب وصنّاع المحتوى وأصحاب المواقع والمدونات الإلكترونية.&lt;/p&gt;
&lt;p&gt;سواء كنت ترغب في تفريغ مقابلة صحفية، أو تحويل محاضرة جامعية إلى نص، أو إعداد مقال انطلاقًا من فيديو منشور على الإنترنت، فإن هناك مجموعة من الأدوات التي تتيح لك إنجاز هذه المهمة بسهولة، دون الحاجة إلى كتابة كل كلمة يدويًا.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;أفضل الأدوات لتحويل الفيديو إلى نص&lt;/h3&gt;
&lt;p&gt;تتوفر العديد من المواقع والأدوات التي تساعد على تحويل الفيديوهات إلى نصوص مكتوبة، وتختلف فيما بينها من حيث الدقة واللغات المدعومة والميزات المتاحة.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;1. TurboScribe: أداة متخصصة في تفريغ الفيديوهات&lt;/h4&gt;
&lt;p&gt;تُعد TurboScribe من الأدوات المعروفة في مجال تحويل الملفات الصوتية والفيديوهات إلى نصوص مكتوبة باستخدام الذكاء الاصطناعي. وتتيح للمستخدم رفع ملف الفيديو واختيار اللغة المناسبة، ثم استخراج الكلام وتحويله إلى نص يمكن مراجعته وتعديله.&lt;/p&gt;&lt;p&gt;&lt;a href="https://turboscribe.ai/"&gt;زيارة موقع TurboScribe&lt;/a&gt;&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkaCPslDbDUkpx3B6K72L3CfIv10yigkZ4Mf-JuwyecuaRlWLzX40lewTvDNcNlUXi1sUZelX93CLesOSe0ErOGqCjNHSSBFV7BkdK9VeCuJ94VV7syOt7vRNxg8Z0__F5cC1dn0Ji9jXpGIc3EqGeYt_nbMq3bYCAtGSjvaOwd680J0Y9P24uYV9cKbe2/s640/imageedit_1_6315991340.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="TurboScribe" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkaCPslDbDUkpx3B6K72L3CfIv10yigkZ4Mf-JuwyecuaRlWLzX40lewTvDNcNlUXi1sUZelX93CLesOSe0ErOGqCjNHSSBFV7BkdK9VeCuJ94VV7syOt7vRNxg8Z0__F5cC1dn0Ji9jXpGIc3EqGeYt_nbMq3bYCAtGSjvaOwd680J0Y9P24uYV9cKbe2/s1600/imageedit_1_6315991340.webp" title="TurboScribe" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;وتدعم الأداة اللغة العربية، مما يجعلها خيارًا مناسبًا لمن يرغبون في تفريغ المحاضرات والمقابلات والتسجيلات باللغة العربية.&lt;/p&gt;
&lt;p&gt;ومن أبرز مميزاتها إمكانية التعامل مع ملفات صوتية ومرئية متعددة، وتوفير خيارات لتصدير النصوص بصيغ مختلفة، بحسب الميزات المتاحة في الحساب.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;طريقة الاستخدام:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;الدخول إلى الموقع الرسمي.&lt;/li&gt;
&lt;li&gt;رفع ملف الفيديو المراد تحويله.&lt;/li&gt;
&lt;li&gt;اختيار اللغة العربية.&lt;/li&gt;
&lt;li&gt;بدء عملية التفريغ الصوتي.&lt;/li&gt;
&lt;li&gt;مراجعة النص الناتج وحفظه.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;وتناسب هذه الأداة الأشخاص الذين يرغبون في استخراج النص الكامل من الفيديو ثم استخدامه في إعداد مقال أو تقرير صحفي.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;2. Notta: تحويل التسجيلات والمقابلات إلى نصوص&lt;/h4&gt;
&lt;p&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYTjcPO0bRE0bCDi3_a5Q9agDQNlpsw_DBtfOjpWuqO-lrpxB_eRklC8A1QPoB7KgssBsClt-T0QnecWMFUiZqOD0taqeksgxvvkjcXa5oZ-8CfPKo60dqWj_fW8_RoOSDZeA8NJVqxnbEwAQCu2qxMyRwyrARNalLrKnWqW9fU0n1Og9SXuHqWCstTq1o/s640/imageedit_3_7262223422.webp" style="margin-left: 1em; margin-right: 1em; text-align: center;"&gt;&lt;img alt="Notta" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYTjcPO0bRE0bCDi3_a5Q9agDQNlpsw_DBtfOjpWuqO-lrpxB_eRklC8A1QPoB7KgssBsClt-T0QnecWMFUiZqOD0taqeksgxvvkjcXa5oZ-8CfPKo60dqWj_fW8_RoOSDZeA8NJVqxnbEwAQCu2qxMyRwyrARNalLrKnWqW9fU0n1Og9SXuHqWCstTq1o/s1600/imageedit_3_7262223422.webp" title="Notta" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;p&gt;توفر Notta مجموعة من الأدوات التي تساعد على تحويل التسجيلات الصوتية وبعض ملفات الفيديو إلى نصوص مكتوبة، مع إمكانية تنظيم المحتوى وتحريره بعد انتهاء عملية التفريغ.&lt;/p&gt;
&lt;p&gt;ويمكن الاستفادة منها في تفريغ الاجتماعات والمقابلات والمحاضرات، ثم إعادة استخدام النص الناتج في إعداد المستندات والتقارير.&lt;/p&gt;
&lt;p&gt;وتختلف الميزات المتاحة بحسب نوع الحساب واللغة وصيغة الملف، لذلك يُفضّل التحقق من خيارات الاستيراد والتفريغ قبل البدء.&lt;/p&gt;
&lt;p&gt;وتُعد Notta خيارًا مناسبًا للمستخدمين الذين يحتاجون إلى تحويل التسجيلات إلى نصوص منظمة يسهل الرجوع إليها وتحريرها.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.notta.ai/"&gt;زيارة موقع Notta&lt;/a&gt;&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;3. VEED.IO: استخراج النص وإنشاء ترجمة للفيديو&lt;/h4&gt;
&lt;p&gt;تجمع منصة VEED.IO بين تحرير الفيديو وأدوات إنشاء الترجمات النصية، إذ تتيح للمستخدمين استخراج الكلام من المقاطع المصورة وتحويله إلى نص، بالإضافة إلى إنشاء ترجمة يمكن إظهارها داخل الفيديو.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-x52Zby2BIWP8HT4mzCLkAh4vW8nRhVjF1l24U3b0XktLvk6UUEdIh8xhlXmzYeyRgcefpdcI7Uh1N1xilBDvRAlVqrhWS9BkQ8Bb9NjuHbz3sdVXOXxQc0EQyDRbI-9jHwiQLuV0Loez-lMJVOCUNPlVA6UPHPmnzMViZQV7XCwInJjhWq9x-Eeth_fJ/s640/imageedit_5_9683383249.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="VEED.IO" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-x52Zby2BIWP8HT4mzCLkAh4vW8nRhVjF1l24U3b0XktLvk6UUEdIh8xhlXmzYeyRgcefpdcI7Uh1N1xilBDvRAlVqrhWS9BkQ8Bb9NjuHbz3sdVXOXxQc0EQyDRbI-9jHwiQLuV0Loez-lMJVOCUNPlVA6UPHPmnzMViZQV7XCwInJjhWq9x-Eeth_fJ/s1600/imageedit_5_9683383249.webp" title="VEED.IO" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;وتفيد هذه المنصة صنّاع المحتوى الذين ينشرون مقاطعهم على منصات التواصل الاجتماعي، ويرغبون في إضافة ترجمة إلى الفيديوهات أو استخراج النصوص للاستفادة منها في كتابة المنشورات والمقالات.&lt;/p&gt;
&lt;p&gt;ومن أبرز استخداماتها:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;إنشاء ترجمة تلقائية للفيديو.&lt;/li&gt;
&lt;li&gt;تعديل النصوص الناتجة عن التفريغ.&lt;/li&gt;
&lt;li&gt;مزامنة الترجمة مع الصوت.&lt;/li&gt;
&lt;li&gt;الاستفادة من النص المستخرج في إعداد محتوى مكتوب.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;وقد تختلف إمكانات التصدير وحدود الاستخدام بحسب الخطة المتاحة، لذا يُنصح بمراجعة تفاصيل الخدمة قبل استخدامها.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.veed.io/"&gt;زيارة موقع VEED.IO&lt;/a&gt;&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;4. YouTube: استخراج النص من الفيديوهات المنشورة&lt;/h4&gt;
&lt;p&gt;إذا كان الفيديو منشورًا على يوتيوب، فقد لا تحتاج إلى استخدام أداة خارجية لاستخراج الكلام منه، إذ يوفر الموقع ميزة عرض النص المكتوب لبعض الفيديوهات التي تتوفر لها ترجمات أو نصوص تلقائية.&lt;/p&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvo6u7mlqmQObDHVPs-lLzlFCU5pAqPECEhG36ffuK3urXNMNwYEKOnUxCTNHtdvkLjUOnsK0OeNlEZaUwwnPMabqJrqLZ7vBYtKA9r5NF5INrsaitnmmolgqY4QxemmaKD24MlOAMyHD27kVWMzScGjYsLix9vUdLUeswWaPUXU0t3aJ-JAdj5Zym9po1/s640/imageedit_7_9221691763.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="YouTube" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvo6u7mlqmQObDHVPs-lLzlFCU5pAqPECEhG36ffuK3urXNMNwYEKOnUxCTNHtdvkLjUOnsK0OeNlEZaUwwnPMabqJrqLZ7vBYtKA9r5NF5INrsaitnmmolgqY4QxemmaKD24MlOAMyHD27kVWMzScGjYsLix9vUdLUeswWaPUXU0t3aJ-JAdj5Zym9po1/s1600/imageedit_7_9221691763.webp" title="YouTube" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p&gt;ويمكن الاستفادة من هذه الميزة في استخراج محتوى المحاضرات والمقابلات والشروحات، ثم تحويله إلى مقال أو تقرير بعد مراجعته وإعادة صياغته.&lt;/p&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/"&gt;زيارة موقع YouTube&lt;/a&gt;&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;&lt;strong&gt;خطوات استخراج النص:&lt;/strong&gt;&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;افتح الفيديو المطلوب على يوتيوب.&lt;/li&gt;
&lt;li&gt;ابحث عن خيار «عرض النص المكتوب» (Show transcript)، إذا كان متاحًا.&lt;/li&gt;
&lt;li&gt;افتح لوحة النص المصاحب للفيديو.&lt;/li&gt;
&lt;li&gt;انسخ النص المتاح واستخدمه في محرر النصوص.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;ويجب الانتباه إلى أن هذه الميزة لا تتوفر بالضرورة في جميع الفيديوهات، كما قد تحتوي النصوص التلقائية على أخطاء تحتاج إلى التصحيح.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/576958100236516656/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/converting-video-to-text-using-artificial-intelligence.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/576958100236516656" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/576958100236516656" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/converting-video-to-text-using-artificial-intelligence.html" rel="alternate" title="كيفية تحويل الفيديو إلى نص مكتوب باستخدام الذكاء الاصطناعي" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOqmOB0zUDRycuvdDCIDXucS8bz2pmk9V6Tcx_CbqDU77FcoJl3bGzmYaEMP4U8Ew38aU8jqdmHmdE1NBoK73e-SxTM_Fy543Ulu7z5U5p8lXNGHOaxe5Ri5fI7jf7lOy1W_12P_ZEidhSOds6x0E8ocPTNBzhXI0l2BS1D7Qj_ewc0s1gQu80NCTV6fZP/s72-c/imageedit_1_7505088793.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-895737409686910627</id><published>2026-10-12T09:20:44.746+03:00</published><updated>2026-10-12T09:24:39.073+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">رفع الصور والملفات وتخزينها وعرضها File Storage في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwudbSR5mpaYigO1GPGij7Qy4U52_gSB4V_d0wGJGGLd2lZ0HD2p_kqGMU1UDPSstS02vIbjOtChlWTGLQfR4ZmpabHojGex4c57qKx4Jo6KfbdV-5AfD3rdPihz5E0DJlOAB7KHUkSjquyzlWNBU0Flz0JaZetGXqTLA6rWmrpAcAyldPssHTTsdE04Ak/s640/imageedit_1_6314910003.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="رفع الملفات والصور وتخزينها File Storage" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwudbSR5mpaYigO1GPGij7Qy4U52_gSB4V_d0wGJGGLd2lZ0HD2p_kqGMU1UDPSstS02vIbjOtChlWTGLQfR4ZmpabHojGex4c57qKx4Jo6KfbdV-5AfD3rdPihz5E0DJlOAB7KHUkSjquyzlWNBU0Flz0JaZetGXqTLA6rWmrpAcAyldPssHTTsdE04Ak/s1600/imageedit_1_6314910003.webp" title="رفع الملفات والصور وتخزينها File Storage" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;رفع الصور والملفات وتخزينها وعرضها في Laravel&lt;/h3&gt;&lt;p&gt;بعد أن تعلمنا في الدرس السابق مفهوم &lt;strong&gt;Authorization&lt;/strong&gt; وكيفية التحكم في الصلاحيات باستخدام Gates وPolicies، سننتقل في هذا الدرس إلى موضوع عملي ومهم جدًا في معظم تطبيقات Laravel، وهو &lt;strong&gt;رفع الملفات وتخزينها وإدارتها&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;معظم التطبيقات الحديثة تحتاج إلى التعامل مع الملفات بطريقة أو بأخرى.&lt;/p&gt;&lt;p&gt;فمثلًا قد يحتاج المستخدم إلى:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;رفع صورة شخصية.&lt;/li&gt;&lt;li&gt;رفع صورة لمقال.&lt;/li&gt;&lt;li&gt;رفع ملف PDF.&lt;/li&gt;&lt;li&gt;رفع مستند.&lt;/li&gt;&lt;li&gt;رفع صورة غلاف.&lt;/li&gt;&lt;li&gt;رفع ملفات متعددة.&lt;/li&gt;&lt;li&gt;استبدال ملف قديم بملف جديد.&lt;/li&gt;&lt;li&gt;حذف الملفات التي لم تعد مستخدمة.&lt;/li&gt;&lt;li&gt;عرض الملفات والصور داخل الموقع.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لو أردنا تنفيذ هذه العمليات باستخدام PHP التقليدية فقط، سنحتاج إلى التعامل مع مسارات الملفات والمجلدات وأسماء الملفات والصلاحيات وغيرها من التفاصيل.&lt;/p&gt;&lt;p&gt;لكن Laravel يوفر لنا نظامًا مريحًا يسمى &lt;strong&gt;Filesystem&lt;/strong&gt;، ويعتمد Laravel على طبقة Flysystem لتوحيد طريقة التعامل مع أنظمة التخزين المختلفة، سواء كان التخزين محليًا على الخادم أو باستخدام خدمات مثل Amazon S3.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنتعلم كيف نستخدم هذا النظام خطوة بخطوة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو File Storage في Laravel؟&lt;/h3&gt;&lt;p&gt;مصطلح &lt;strong&gt;File Storage&lt;/strong&gt; يعني نظام تخزين الملفات الذي يستخدمه التطبيق.&lt;/p&gt;&lt;p&gt;بدل أن نتعامل مباشرة مع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/...
&lt;/pre&gt;
&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/uploads/...
&lt;/pre&gt;&lt;p&gt;يمكننا استخدام Laravel Storage API:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::put(...)
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::disk(...)
&lt;/pre&gt;&lt;p&gt;أو التعامل مباشرة مع الملف المرفوع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;file(...)
&lt;/pre&gt;&lt;p&gt;Laravel يجعل عملية التخزين مستقلة نسبيًا عن مكان التخزين الفعلي.&lt;/p&gt;&lt;p&gt;فيمكن أن يكون الملف موجودًا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Local Server
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Amazon S3
&lt;/pre&gt;&lt;p&gt;أو نظام تخزين متوافق مع S3.&lt;/p&gt;&lt;p&gt;والميزة المهمة هي أن كود التطبيق يمكن أن يبقى متشابهًا إلى حد كبير عند تغيير Driver التخزين.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نحتاج إلى Storage بدل حفظ الملفات عشوائيًا؟&lt;/h3&gt;&lt;p&gt;لنفترض أنك تريد حفظ صور المستخدمين.&lt;/p&gt;&lt;p&gt;قد تفكر في وضع الصور مباشرة داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/uploads
&lt;/pre&gt;&lt;p&gt;قد يعمل ذلك في بعض المشاريع الصغيرة، لكن Laravel يوفر نظامًا أكثر تنظيمًا.&lt;/p&gt;&lt;p&gt;يمكن أن يكون لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/public
&lt;/pre&gt;&lt;p&gt;ثم نستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan storage:link
&lt;/pre&gt;&lt;p&gt;ليصبح بالإمكان الوصول إلى الملفات العامة من خلال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/storage
&lt;/pre&gt;&lt;p&gt;وهذا هو الأسلوب الذي توصي به Laravel للملفات التي يجب أن تكون متاحة للعامة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;فهم مجلد storage&lt;/h3&gt;&lt;p&gt;من أهم المجلدات التي يجب أن تعرفها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/
&lt;/pre&gt;&lt;p&gt;ويحتوي على ملفات يتم إنشاؤها أو استخدامها بواسطة التطبيق.&lt;/p&gt;&lt;p&gt;ومن ضمنه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app
storage/framework
storage/logs
&lt;/pre&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/public
&lt;/pre&gt;&lt;p&gt;فيمكن استخدامه للملفات التي تريد أن تكون متاحة للعامة، مثل صور المستخدمين أو الصور المرفوعة للمقالات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو Disk في Laravel؟&lt;/h3&gt;&lt;p&gt;كلمة &lt;strong&gt;Disk&lt;/strong&gt; في Laravel تعني إعدادًا يحدد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;أين؟
وكيف؟
سيتم تخزين الملفات.
&lt;/pre&gt;&lt;p&gt;إعدادات الأقراص موجودة في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;config/filesystems.php
&lt;/pre&gt;&lt;p&gt;يمكنك تعريف عدة Disks، وكل Disk يمكن أن يستخدم Driver مختلفًا.&lt;/p&gt;&lt;p&gt;مثلًا قد يكون لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;local
public
s3
&lt;/pre&gt;&lt;p&gt;الفكرة تصبح:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Application
     ↓
Storage
     ↓
Disk
     ↓
Driver
     ↓
Storage Location
&lt;/pre&gt;&lt;h3&gt;الـ Local Disk&lt;/h3&gt;&lt;p&gt;الـ Local Disk يستخدم لتخزين الملفات محليًا على الخادم.&lt;/p&gt;&lt;p&gt;في الإعدادات الافتراضية، الملفات التي يستخدمها الـ local disk تكون ضمن مسار التخزين المحلي المحدد في &lt;code inline=""&gt;filesystems.php&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::disk('local')-&amp;gt;put(
    'example.txt',
    'Hello Laravel'
);
&lt;/pre&gt;&lt;p&gt;سيتم حفظ الملف داخل المسار المرتبط بهذا الـ Disk.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الـ Public Disk&lt;/h3&gt;&lt;p&gt;هناك Disk مخصص للملفات التي تريد جعلها متاحة للعامة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public
&lt;/pre&gt;&lt;p&gt;وبشكل افتراضي يستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/public
&lt;/pre&gt;&lt;p&gt;ولكي تصبح هذه الملفات قابلة للوصول من المتصفح، نستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan storage:link
&lt;/pre&gt;&lt;p&gt;Laravel ينشئ Symbolic Link بين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/storage
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/public
&lt;/pre&gt;&lt;p&gt;وبالتالي يستطيع خادم الويب الوصول إلى الملفات العامة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء Storage Link&lt;/h3&gt;&lt;p&gt;بعد إنشاء مشروع Laravel وتشغيله، نفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan storage:link
&lt;/pre&gt;&lt;p&gt;بعد ذلك سيكون لدينا رابط مشابه لـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/storage
&lt;/pre&gt;&lt;p&gt;يشير إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/public
&lt;/pre&gt;&lt;p&gt;لا تحتاج إلى تنفيذ هذا الأمر في كل مرة ترفع فيها ملفًا.&lt;/p&gt;&lt;p&gt;عادةً يتم تنفيذه عند تجهيز المشروع أو البيئة التي تحتاج إلى هذا الرابط.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أول عملية تخزين باستخدام Storage&lt;/h3&gt;&lt;p&gt;لنبدأ بمثال بسيط.&lt;/p&gt;&lt;p&gt;في Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Support\Facades\Storage;

Storage::disk('public')-&amp;gt;put(
    'example.txt',
    'Hello from Laravel'
);
&lt;/pre&gt;&lt;p&gt;سيتم تخزين الملف على Disk:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public
&lt;/pre&gt;&lt;p&gt;داخل المسار:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;example.txt
&lt;/pre&gt;&lt;p&gt;أي ضمن جذر الـ public disk.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام Storage::put&lt;/h3&gt;&lt;p&gt;يمكنك أيضًا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::put(
    'example.txt',
    'Hello Laravel'
);
&lt;/pre&gt;&lt;p&gt;عند عدم تحديد Disk، سيستخدم Laravel الـ default disk المحدد في إعدادات التخزين.&lt;/p&gt;&lt;p&gt;لكن عندما يكون المشروع واضحًا، قد يكون من الأفضل تحديد الـ Disk عند الحاجة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::disk('public')-&amp;gt;put(
    'example.txt',
    'Hello Laravel'
);
&lt;/pre&gt;&lt;p&gt;حتى يكون واضحًا أين سيتم تخزين الملف.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;رفع الملفات من Form&lt;/h3&gt;&lt;p&gt;الآن نصل إلى الجزء الأهم.&lt;/p&gt;&lt;p&gt;لنفترض أننا نريد إنشاء Form يسمح للمستخدم برفع صورة.&lt;/p&gt;&lt;p&gt;داخل Blade:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST" action="{{ route('profile.update') }}" enctype="multipart/form-data"&amp;gt;
    @csrf

    &amp;lt;label for="avatar"&amp;gt;
        الصورة الشخصية
    &amp;lt;/label&amp;gt;

    &amp;lt;input
        type="file"
        name="avatar"
        id="avatar"
    &amp;gt;

    &amp;lt;button type="submit"&amp;gt;
        رفع الصورة
    &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;p&gt;هناك نقطة مهمة جدًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;enctype="multipart/form-data"
&lt;/pre&gt;&lt;p&gt;بدونها لن يتم إرسال الملف بالطريقة الصحيحة مع Form التقليدي.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نستخدم multipart/form-data؟&lt;/h3&gt;&lt;p&gt;عند إرسال نصوص عادية، يمكن للمتصفح استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;application/x-www-form-urlencoded
&lt;/pre&gt;&lt;p&gt;لكن عندما نرسل ملفات، نحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;multipart/form-data
&lt;/pre&gt;&lt;p&gt;لذلك عند وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;input type="file"&amp;gt;
&lt;/pre&gt;&lt;p&gt;يجب أن نتأكد من وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;enctype="multipart/form-data"
&lt;/pre&gt;&lt;p&gt;في Form.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استقبال الملف داخل Controller&lt;/h3&gt;&lt;p&gt;في Controller يمكننا الوصول إلى الملف باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;file('avatar');
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(Request $request)
{
    $file = $request-&amp;gt;file('avatar');

    // ...
}
&lt;/pre&gt;&lt;p&gt;لكن لا ينبغي أن نبدأ بتخزين الملف مباشرة.&lt;/p&gt;&lt;p&gt;أولًا يجب أن نتحقق منه.&lt;/p&gt;&lt;p&gt;وهنا نستخدم ما تعلمناه في الدرس السابع:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Validation&lt;/strong&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التحقق من الملف قبل تخزينه&lt;/h3&gt;&lt;p&gt;يمكن استخدام قاعدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'avatar' =&amp;gt; ['required', 'image']
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'avatar' =&amp;gt; ['required', 'image'],
]);
&lt;/pre&gt;&lt;p&gt;Laravel يوفر قواعد مخصصة للملفات مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;file
image
mimes
mimetypes
max
min
dimensions
&lt;/pre&gt;&lt;p&gt;كما يوفر Laravel 13 File Validation Rule أكثر مرونة باستخدام &lt;code inline=""&gt;Illuminate\Validation\Rules\File&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;قاعدة image&lt;/h3&gt;&lt;p&gt;يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'image' =&amp;gt; ['required', 'image']
&lt;/pre&gt;&lt;p&gt;قاعدة &lt;code inline=""&gt;image&lt;/code&gt; تتحقق من أن الملف صورة من الأنواع التي يسمح بها Laravel افتراضيًا، ومنها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;jpg
jpeg
png
bmp
gif
webp
&lt;/pre&gt;&lt;p&gt;ولا تسمح قاعدة &lt;code inline=""&gt;image&lt;/code&gt; افتراضيًا بملفات SVG بسبب المخاطر المحتملة المتعلقة بـ XSS، ويمكن السماح بها صراحةً عند الحاجة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تحديد حجم الملف&lt;/h3&gt;&lt;p&gt;من المهم جدًا تحديد حجم الملفات التي يمكن للمستخدم رفعها.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'avatar' =&amp;gt; ['required', 'image', 'max:2048'],
]);
&lt;/pre&gt;&lt;p&gt;هنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;2048 KB
&lt;/pre&gt;&lt;p&gt;تعادل تقريبًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;2 MB
&lt;/pre&gt;&lt;p&gt;وبالتالي لن يسمح التطبيق برفع صورة تتجاوز الحد المحدد.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام File Rule في Laravel 13&lt;/h3&gt;&lt;p&gt;Laravel 13 يوفر طريقة أكثر مرونة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Validation\Rules\File;

$validated = $request-&amp;gt;validate([
    'avatar' =&amp;gt; [
        'required',
        File::image()
            -&amp;gt;max('2mb'),
    ],
]);
&lt;/pre&gt;&lt;p&gt;يمكن أيضًا تحديد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;min
max
types
extensions
dimensions
&lt;/pre&gt;&lt;p&gt;باستخدام File Rule.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تحديد أبعاد الصورة&lt;/h3&gt;&lt;p&gt;في بعض التطبيقات لا يكفي التأكد من أن الملف صورة.&lt;/p&gt;&lt;p&gt;قد تريد مثلًا أن تكون صورة الغلاف ضمن أبعاد معينة.&lt;/p&gt;&lt;p&gt;Laravel يوفر التحقق من أبعاد الصور.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Validation\Rule;
use Illuminate\Validation\Rules\File;

$validated = $request-&amp;gt;validate([
    'cover' =&amp;gt; [
        'required',
        File::image()-&amp;gt;dimensions(
            Rule::dimensions()
                -&amp;gt;minWidth(1200)
                -&amp;gt;minHeight(600)
        ),
    ],
]);
&lt;/pre&gt;&lt;p&gt;وهذا مفيد جدًا عند بناء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;صور المقالات
صور المنتجات
صور الأغلفة
صور الحسابات
&lt;/pre&gt;&lt;p&gt;وغيرها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تخزين الملف باستخدام store&lt;/h3&gt;&lt;p&gt;بعد نجاح Validation يمكننا تخزين الملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = $request-&amp;gt;file('avatar')-&amp;gt;store('avatars');
&lt;/pre&gt;&lt;p&gt;سيقوم Laravel بتخزين الملف داخل المجلد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;avatars
&lt;/pre&gt;&lt;p&gt;على الـ Disk الافتراضي.&lt;/p&gt;&lt;p&gt;والأهم أن Laravel يعيد لك المسار الذي تم تخزين الملف فيه.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;avatars/AbCd1234.jpg
&lt;/pre&gt;&lt;p&gt;يمكنك بعد ذلك حفظ هذا المسار في قاعدة البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تحديد Disk أثناء التخزين&lt;/h3&gt;&lt;p&gt;يمكنك تحديد Disk:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = $request-&amp;gt;file('avatar')-&amp;gt;store(
    'avatars',
    'public'
);
&lt;/pre&gt;&lt;p&gt;الآن أصبح التخزين على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public
&lt;/pre&gt;&lt;p&gt;داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;avatars/
&lt;/pre&gt;&lt;p&gt;وبالتالي يكون المسار مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;avatars/random-name.jpg
&lt;/pre&gt;&lt;p&gt;Laravel يوفر &lt;code inline=""&gt;store&lt;/code&gt; وطرقًا أخرى لتخزين الملفات المرفوعة مع إنشاء أسماء فريدة تلقائيًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا لا نستخدم اسم الملف الذي يرسله المستخدم؟&lt;/h3&gt;&lt;p&gt;قد يصل الملف مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;my-photo.jpg
&lt;/pre&gt;&lt;p&gt;لكن لا يفضل أن تعتمد على هذا الاسم كاسم التخزين النهائي.&lt;/p&gt;&lt;p&gt;هناك عدة أسباب، منها:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;احتمال تكرار الأسماء.&lt;/li&gt;&lt;li&gt;مشاكل تتعلق بالمسارات.&lt;/li&gt;&lt;li&gt;صعوبة إدارة الملفات.&lt;/li&gt;&lt;li&gt;احتمالية وجود أسماء غير مناسبة للرابط.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;عند استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;store()
&lt;/pre&gt;&lt;p&gt;يقوم Laravel بإنشاء اسم فريد للملف ويعيد لك المسار الناتج.&lt;/p&gt;&lt;p&gt;وهذا مناسب جدًا لمعظم حالات رفع الملفات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;حفظ مسار الملف في قاعدة البيانات&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;ويحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
title
content
image
user_id
&lt;/pre&gt;&lt;p&gt;عند رفع صورة المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = $request-&amp;gt;file('image')-&amp;gt;store(
    'articles',
    'public'
);
&lt;/pre&gt;&lt;p&gt;يمكننا حفظ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path
&lt;/pre&gt;&lt;p&gt;في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;image
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles/a8d92f3.jpg
&lt;/pre&gt;&lt;p&gt;نلاحظ أننا لا نحتاج إلى حفظ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;https://example.com/storage/articles/a8d92f3.jpg
&lt;/pre&gt;&lt;p&gt;داخل قاعدة البيانات.&lt;/p&gt;&lt;p&gt;الأفضل عادةً تخزين &lt;strong&gt;المسار&lt;/strong&gt; فقط، ثم إنشاء URL عند الحاجة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء URL للملف&lt;/h3&gt;&lt;p&gt;بعد تخزين الملف على Public Disk يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::url($path)
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$url = Storage::url($article-&amp;gt;image);
&lt;/pre&gt;&lt;p&gt;وفي حالة الـ local public disk، ينتج Laravel عادةً URL يبدأ بمسار:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/storage/...
&lt;/pre&gt;&lt;p&gt;كما يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;asset('storage/' . $article-&amp;gt;image)
&lt;/pre&gt;&lt;p&gt;بعد إنشاء &lt;code inline=""&gt;storage:link&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;عرض الصورة داخل Blade&lt;/h3&gt;&lt;p&gt;إذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;image
&lt;/pre&gt;&lt;p&gt;يمكننا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;img
    src="{{ Storage::url($article-&amp;gt;image) }}"
    alt="{{ $article-&amp;gt;title }}"
&amp;gt;
&lt;/pre&gt;&lt;p&gt;ويجب استيراد Storage في المكان الذي تستخدم فيه Facade داخل PHP:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Support\Facades\Storage;
&lt;/pre&gt;&lt;p&gt;أما في Blade فيمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" style="text-align: right;"&gt;{{ Storage::url($article-&amp;gt;image) }}
&lt;/pre&gt;&lt;h3&gt;مثال كامل لرفع صورة مقال&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا Route:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::post('/articles', [ArticleController::class, 'store'])
    -&amp;gt;name('articles.store');
&lt;/pre&gt;&lt;p&gt;ولدينا Form:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form
    method="POST"
    action="{{ route('articles.store') }}"
    enctype="multipart/form-data"
&amp;gt;
    @csrf

    &amp;lt;div&amp;gt;
        &amp;lt;label for="title"&amp;gt;عنوان المقال&amp;lt;/label&amp;gt;

        &amp;lt;input
            type="text"
            name="title"
            id="title"
            value="{{ old('title') }}"
        &amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div&amp;gt;
        &amp;lt;label for="content"&amp;gt;المحتوى&amp;lt;/label&amp;gt;

        &amp;lt;textarea
            name="content"
            id="content"
        &amp;gt;{{ old('content') }}&amp;lt;/textarea&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;div&amp;gt;
        &amp;lt;label for="image"&amp;gt;صورة المقال&amp;lt;/label&amp;gt;

        &amp;lt;input
            type="file"
            name="image"
            id="image"
        &amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;button type="submit"&amp;gt;
        نشر المقال
    &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;Controller&lt;/h3&gt;&lt;p&gt;داخل Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Models\Article;
use Illuminate\Http\Request;

public function store(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'title' =&amp;gt; ['required', 'string', 'max:255'],
        'content' =&amp;gt; ['required', 'string'],
        'image' =&amp;gt; ['required', 'image', 'max:2048'],
    ]);

    $path = $request-&amp;gt;file('image')-&amp;gt;store(
        'articles',
        'public'
    );

    $article = Article::create([
        'title' =&amp;gt; $validated['title'],
        'content' =&amp;gt; $validated['content'],
        'image' =&amp;gt; $path,
        'user_id' =&amp;gt; $request-&amp;gt;user()-&amp;gt;id,
    ]);

    return redirect()
        -&amp;gt;route('articles.show', $article)
        -&amp;gt;with('success', 'تم نشر المقال بنجاح.');
}
&lt;/pre&gt;&lt;p&gt;لاحظ التسلسل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Form
 ↓
Request
 ↓
Validation
 ↓
Store File
 ↓
Get Path
 ↓
Save Path in Database
 ↓
Redirect
&lt;/pre&gt;&lt;p&gt;وهذا نمط مهم جدًا ستستخدمه في الكثير من التطبيقات.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;إضافة عمود image إلى Migration&lt;/h3&gt;&lt;p&gt;إذا لم يكن جدول المقالات يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;image
&lt;/pre&gt;&lt;p&gt;يمكن إنشاء Migration:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration add_image_to_articles_table --table=articles
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Schema::table('articles', function (Blueprint $table) {
    $table-&amp;gt;string('image')-&amp;gt;nullable();
});
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;الآن يمكن تخزين مسار الصورة داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.image
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;لماذا نجعل image nullable؟&lt;/h3&gt;&lt;p&gt;قد يكون لدينا مقالات بدون صورة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article A
image = null
&lt;/pre&gt;&lt;p&gt;ومقال آخر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article B
image = articles/example.jpg
&lt;/pre&gt;&lt;p&gt;لذلك يمكن أن يكون العمود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('image')-&amp;gt;nullable();
&lt;/pre&gt;&lt;p&gt;أما إذا كانت الصورة إلزامية لكل مقال، فيمكن تصميم العمود وقواعد Validation وفقًا لذلك.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التعامل مع الصور الاختيارية&lt;/h3&gt;&lt;p&gt;إذا كانت الصورة غير إلزامية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'title' =&amp;gt; ['required', 'string', 'max:255'],
    'content' =&amp;gt; ['required', 'string'],
    'image' =&amp;gt; ['nullable', 'image', 'max:2048'],
]);
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = null;

if ($request-&amp;gt;hasFile('image')) {
    $path = $request-&amp;gt;file('image')-&amp;gt;store(
        'articles',
        'public'
    );
}
&lt;/pre&gt;
&lt;p&gt;وبعد ذلك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create([
    'title' =&amp;gt; $validated['title'],
    'content' =&amp;gt; $validated['content'],
    'image' =&amp;gt; $path,
    'user_id' =&amp;gt; $request-&amp;gt;user()-&amp;gt;id,
]);
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;التحقق من وجود الملف&lt;/h3&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;hasFile('image')
&lt;/pre&gt;&lt;p&gt;للتأكد من وجود ملف مرفوع.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if ($request-&amp;gt;hasFile('image')) {
    // يوجد ملف
}
&lt;/pre&gt;&lt;p&gt;ويمكن بعدها الوصول إليه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;file('image')
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;معرفة معلومات الملف&lt;/h3&gt;&lt;p&gt;يمكنك التعامل مع الملف المرفوع واستخراج معلومات عنه عند الحاجة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$file = $request-&amp;gt;file('image');
&lt;/pre&gt;&lt;p&gt;ثم يمكن التعامل مع خصائص الملف وفق APIs الخاصة بالملفات المرفوعة.&lt;/p&gt;&lt;p&gt;لكن من الأفضل ألا تعتمد على اسم الملف الذي أرسله المستخدم باعتباره وسيلة تحقق أمني.&lt;/p&gt;&lt;p&gt;Validation يجب أن يكون هو الأساس.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;mimes وmimetypes&lt;/h3&gt;&lt;p&gt;يمكن تحديد أنواع الملفات المقبولة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'image' =&amp;gt; [
    'required',
    'mimes:jpg,jpeg,png,webp',
    'max:2048',
],
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'document' =&amp;gt; [
    'required',
    'mimetypes:application/pdf',
    'max:5120',
],
&lt;/pre&gt;&lt;p&gt;Laravel يوضح أن &lt;code inline=""&gt;mimes&lt;/code&gt; يعتمد على قراءة محتوى الملف وتخمين MIME type، وليس مجرد الاعتماد على امتداد الاسم، بينما &lt;code inline=""&gt;mimetypes&lt;/code&gt; يسمح بتحديد MIME types مباشرة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;رفع ملفات PDF&lt;/h3&gt;&lt;p&gt;ليس كل شيء صورًا.&lt;/p&gt;&lt;p&gt;قد تريد السماح للمستخدم برفع PDF:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'document' =&amp;gt; [
    'required',
    'mimes:pdf',
    'max:10240',
],
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = $request-&amp;gt;file('document')-&amp;gt;store(
    'documents',
    'public'
);
&lt;/pre&gt;&lt;p&gt;النتيجة مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;documents/random-file.pdf
&lt;/pre&gt;&lt;p&gt;ثم يمكنك حفظ المسار في قاعدة البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;رفع ملف باسم محدد&lt;/h3&gt;&lt;p&gt;في بعض الحالات قد تريد تحديد اسم الملف بنفسك.&lt;/p&gt;&lt;p&gt;Laravel يوفر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storeAs()
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = $request-&amp;gt;file('avatar')-&amp;gt;storeAs(
    'avatars',
    'user-' . $request-&amp;gt;user()-&amp;gt;id . '.jpg',
    'public'
);
&lt;/pre&gt;&lt;p&gt;لكن يجب استخدام هذه الطريقة بحذر لتجنب الكتابة فوق ملفات موجودة بنفس الاسم.&lt;/p&gt;&lt;p&gt;في معظم الحالات، &lt;code inline=""&gt;store()&lt;/code&gt; مع اسم فريد يكون خيارًا أبسط.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;putFile و putFileAs&lt;/h3&gt;&lt;p&gt;يوفر Laravel أيضًا طرقًا مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::putFile(...)
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::putFileAs(...)
&lt;/pre&gt;&lt;p&gt;وهي مفيدة عندما تريد تخزين ملف باستخدام Storage API مباشرةً.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = Storage::disk('public')-&amp;gt;putFile(
    'documents',
    $request-&amp;gt;file('document')
);
&lt;/pre&gt;&lt;p&gt;وتعيد العملية المسار الذي تم تخزين الملف فيه.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;حذف الملفات&lt;/h3&gt;&lt;p&gt;رفع الملفات ليس الجزء الوحيد.&lt;/p&gt;&lt;p&gt;ماذا يحدث إذا حذف المستخدم المقال؟&lt;/p&gt;&lt;p&gt;إذا حذفت السجل من قاعدة البيانات وتركت الصورة، فقد تتراكم الملفات غير المستخدمة.&lt;/p&gt;&lt;p&gt;لذلك يمكن حذف الملف باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::disk('public')-&amp;gt;delete($article-&amp;gt;image);
&lt;/pre&gt;&lt;p&gt;ثم حذف المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::disk('public')-&amp;gt;delete($article-&amp;gt;image);

$article-&amp;gt;delete();
&lt;/pre&gt;&lt;p&gt;ويجب التأكد من أن المسار موجود وغير فارغ قبل الحذف عند الحاجة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استبدال صورة قديمة&lt;/h3&gt;&lt;p&gt;لنفترض أن المستخدم يريد تغيير صورة المقال.&lt;/p&gt;&lt;p&gt;يجب أن تكون العملية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Upload New Image
 ↓
Validation
 ↓
Store New Image
 ↓
Delete Old Image
 ↓
Update Database
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if ($request-&amp;gt;hasFile('image')) {
    $newPath = $request-&amp;gt;file('image')-&amp;gt;store(
        'articles',
        'public'
    );

    if ($article-&amp;gt;image) {
        Storage::disk('public')-&amp;gt;delete($article-&amp;gt;image);
    }

    $article-&amp;gt;update([
        'image' =&amp;gt; $newPath,
    ]);
}
&lt;/pre&gt;&lt;p&gt;هذه الطريقة تمنع تراكم الصور القديمة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ماذا عن الملفات الخاصة؟&lt;/h3&gt;&lt;p&gt;ليست كل الملفات يجب أن تكون Public.&lt;/p&gt;&lt;p&gt;قد يكون لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;invoice.pdf
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;private-document.pdf
&lt;/pre&gt;&lt;p&gt;لا تريد أن يستطيع أي شخص الوصول إليه بمجرد معرفة الرابط.&lt;/p&gt;&lt;p&gt;في هذه الحالة لا ينبغي أن تضعه ضمن التخزين العام بطريقة تسمح بالوصول المباشر.&lt;/p&gt;&lt;p&gt;يمكن استخدام Disk خاص، ثم تقديم الملف للمستخدم المصرح له بعد التحقق من Authorization.&lt;/p&gt;&lt;p&gt;وهنا يظهر الربط بين درسنا السابق وهذا الدرس:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
+
Authorization
+
Storage
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;مثال على ملف خاص&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users/{id}/documents/report.pdf
&lt;/pre&gt;&lt;p&gt;ولا نريد أن يكون الملف متاحًا للعامة.&lt;/p&gt;&lt;p&gt;يمكن تخزينه على Disk خاص:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$path = $request-&amp;gt;file('document')-&amp;gt;store(
    'documents'
);
&lt;/pre&gt;&lt;p&gt;ثم عندما يريد المستخدم تحميله، نتحقق أولًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$this-&amp;gt;authorize('view', $document);
&lt;/pre&gt;&lt;p&gt;وبعد نجاح Authorization يمكن تقديم الملف بالطريقة المناسبة.&lt;/p&gt;&lt;p&gt;وهذا أفضل من نشر الملفات الحساسة على Public Disk.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Public أم Private؟&lt;/h3&gt;&lt;p&gt;يمكن تبسيط القرار كالتالي:&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;Public&lt;/h4&gt;&lt;p&gt;استخدمه للملفات التي يمكن للجميع رؤيتها.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;صور المقالات العامة
صور المنتجات
الصور العامة
&lt;/pre&gt;&lt;h4 style="text-align: right;"&gt;Private&lt;/h4&gt;&lt;p&gt;استخدمه للملفات التي تحتاج صلاحيات.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;الفواتير
المستندات الشخصية
التقارير الخاصة
ملفات المستخدم الخاصة
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;Storage::url&lt;/h3&gt;&lt;p&gt;عندما تحتاج إلى إنشاء URL لملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$url = Storage::url($path);
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$url = Storage::disk('public')-&amp;gt;url(
    $article-&amp;gt;image
);
&lt;/pre&gt;&lt;p&gt;ويوفر Laravel طريقة &lt;code inline=""&gt;url()&lt;/code&gt; للحصول على عنوان الملف، ويختلف شكل الرابط حسب الـ Driver المستخدم.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Temporary URLs&lt;/h3&gt;&lt;p&gt;في بعض الأنظمة قد تحتاج إلى رابط مؤقت.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;رابط صالح لمدة 5 دقائق
&lt;/pre&gt;&lt;p&gt;Laravel يوفر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::temporaryUrl(...)
&lt;/pre&gt;&lt;p&gt;ويمكن استخدام هذه الميزة مع أنظمة التخزين التي تدعمها، ومنها local وS3 وفق إعدادات Laravel.&lt;/p&gt;&lt;p&gt;هذه الميزة مفيدة عندما تريد إعطاء المستخدم رابطًا مؤقتًا لملف خاص بدل جعل الملف Public بشكل دائم.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;رفع الصور ومعالجتها في Laravel 13&lt;/h3&gt;&lt;p&gt;Laravel 13 يوفر أيضًا إمكانيات لمعالجة الصور المرفوعة.&lt;/p&gt;&lt;p&gt;مثلًا يمكن إنشاء صورة بحجم معين وتحويلها إلى WebP ثم تخزينها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
$path = $request-&amp;gt;image('avatar')
    -&amp;gt;cover(400, 400)
    -&amp;gt;toWebp()
    -&amp;gt;storePublicly('avatars', 'public');
&lt;/pre&gt;&lt;p&gt;هذا مفيد عندما تريد تقليل حجم الصور أو توحيد أبعادها قبل التخزين. وتوثق Laravel 13 إمكانيات معالجة الصور مثل &lt;code inline=""&gt;cover()&lt;/code&gt; و&lt;code inline=""&gt;toWebp()&lt;/code&gt; ضمن File Storage.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا معالجة الصور مهمة؟&lt;/h3&gt;&lt;p&gt;لنفترض أن المستخدم رفع صورة حجمها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
8 MB
&lt;/pre&gt;&lt;p&gt;وأبعادها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
6000 × 4000
&lt;/pre&gt;&lt;p&gt;بينما الموقع يحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
1200 × 800
&lt;/pre&gt;&lt;p&gt;إذا خزنت الصورة الأصلية كما هي، فقد تزيد:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;مساحة التخزين.&lt;/li&gt;&lt;li&gt;حجم الصفحة.&lt;/li&gt;&lt;li&gt;وقت تحميل الصور.&lt;/li&gt;&lt;li&gt;استهلاك البيانات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لذلك قد يكون من الأفضل في بعض التطبيقات معالجة الصورة قبل تخزينها.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال عملي متكامل&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لنقم ببناء نظام رفع صورة لملف شخصي.&lt;/p&gt;&lt;h3&gt;Form&lt;/h3&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
&amp;lt;form
    method="POST"
    action="{{ route('profile.avatar') }}"
    enctype="multipart/form-data"
&amp;gt;
    @csrf

    &amp;lt;label for="avatar"&amp;gt;
        الصورة الشخصية
    &amp;lt;/label&amp;gt;

    &amp;lt;input
        type="file"
        name="avatar"
        id="avatar"
        accept="image/*"
    &amp;gt;

    @error('avatar')
        &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
    @enderror

    &amp;lt;button type="submit"&amp;gt;
        حفظ الصورة
    &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;h3&gt;Route&lt;/h3&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
Route::post('/profile/avatar', [
    ProfileController::class,
    'updateAvatar',
])-&amp;gt;middleware('auth')
  -&amp;gt;name('profile.avatar');
&lt;/pre&gt;&lt;p&gt;هنا استخدمنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
-&amp;gt;middleware('auth')
&lt;/pre&gt;&lt;p&gt;لأن الصورة مرتبطة بحساب المستخدم.&lt;/p&gt;&lt;h3&gt;Controller&lt;/h3&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

public function updateAvatar(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'avatar' =&amp;gt; [
            'required',
            'image',
            'max:2048',
        ],
    ]);

    $user = $request-&amp;gt;user();

    $newPath = $request-&amp;gt;file('avatar')-&amp;gt;store(
        'avatars',
        'public'
    );

    if ($user-&amp;gt;avatar) {
        Storage::disk('public')-&amp;gt;delete($user-&amp;gt;avatar);
    }

    $user-&amp;gt;update([
        'avatar' =&amp;gt; $newPath,
    ]);

    return back()-&amp;gt;with(
        'success',
        'تم تحديث الصورة الشخصية بنجاح.'
    );
}
&lt;/pre&gt;&lt;h3&gt;عرض الصورة&lt;/h3&gt;&lt;p&gt;في Blade:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;
@if ($user-&amp;gt;avatar)
    &amp;lt;img
        src="{{ Storage::url($user-&amp;gt;avatar) }}"
        alt="{{ $user-&amp;gt;name }}"
    &amp;gt;
@endif
&lt;/pre&gt;&lt;p&gt;وبذلك أصبح لدينا نظام كامل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
Upload Form
 ↓
POST Request
 ↓
Authentication
 ↓
Validation
 ↓
Storage
 ↓
Database
 ↓
Display Image
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;أخطاء شائعة في رفع الملفات&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;نسيان enctype&lt;/b&gt;&lt;/p&gt;&lt;p&gt;من أكثر الأخطاء شيوعًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST"&amp;gt;
&lt;/pre&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form
    method="POST"
    enctype="multipart/form-data"
&amp;gt;
&lt;/pre&gt;&lt;p&gt;إذا كان Form يحتوي على File Input، تأكد من استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;multipart/form-data
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;عدم تشغيل storage:link&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا خزنت الملفات على Public Disk ولم تستطع رؤيتها من المتصفح، تحقق من تشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan storage:link
&lt;/pre&gt;&lt;p&gt;Laravel يستخدم هذا الرابط للوصول إلى الملفات الموجودة في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;storage/app/public
&lt;/pre&gt;&lt;p&gt;من خلال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/storage
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;عدم التحقق من الملف&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لا تفعل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;file('image')-&amp;gt;store(
    'images',
    'public'
);
&lt;/pre&gt;&lt;p&gt;دون Validation في تطبيق حقيقي.&lt;/p&gt;&lt;p&gt;استخدم على الأقل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'image' =&amp;gt; ['required', 'image', 'max:2048']
&lt;/pre&gt;&lt;p&gt;أو File Rule أكثر تفصيلًا.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;الاعتماد على extension فقط&lt;/b&gt;&lt;/p&gt;&lt;p&gt;وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;photo.jpg
&lt;/pre&gt;&lt;p&gt;لا يعني بالضرورة أن الملف صورة صحيحة.&lt;/p&gt;&lt;p&gt;Laravel يوضح أن قواعد مثل &lt;code inline=""&gt;mimes&lt;/code&gt; تتحقق من محتوى الملف لتخمين MIME type، كما أن &lt;code inline=""&gt;extensions&lt;/code&gt; يمكن استخدامها للتحقق من الامتداد المعلن.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;تخزين URL كامل داخل قاعدة البيانات&lt;/b&gt;&lt;/p&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;https://example.com/storage/articles/image.jpg
&lt;/pre&gt;&lt;p&gt;يفضل غالبًا تخزين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles/image.jpg
&lt;/pre&gt;&lt;p&gt;ثم إنشاء URL عند الحاجة باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::url(...)
&lt;/pre&gt;&lt;p&gt;هذا يجعل التطبيق أكثر مرونة عند تغيير النطاق أو Driver التخزين.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;نسيان حذف الملفات القديمة&lt;/b&gt;&lt;/p&gt;&lt;p&gt;عند تحديث صورة المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Old Image
 ↓
New Image
&lt;/pre&gt;&lt;p&gt;إذا لم تحذف القديمة، ستبقى في Storage حتى لو لم يعد هناك أي سجل يشير إليها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أفضل الممارسات&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;استخدم Validation دائمًا&lt;/b&gt;&lt;/p&gt;&lt;p&gt;تحقق من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;نوع الملف
الحجم
الأبعاد
&lt;/pre&gt;&lt;p&gt;بحسب احتياجات التطبيق.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;استخدم أسماء ملفات آمنة وفريدة&lt;/b&gt;&lt;/p&gt;&lt;p&gt;في معظم الحالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;store()
&lt;/pre&gt;&lt;p&gt;خيار ممتاز لأنه يتعامل مع اسم الملف تلقائيًا.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;خزّن المسار وليس الرابط الكامل&lt;/b&gt;&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;avatars/random-file.jpg
&lt;/pre&gt;&lt;p&gt;ثم استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Storage::url()
&lt;/pre&gt;&lt;p&gt;عند الحاجة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;افصل الملفات العامة عن الخاصة&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لا تجعل كل الملفات Public.&lt;/p&gt;&lt;p&gt;اسأل نفسك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع أي شخص رؤية هذا الملف؟
&lt;/pre&gt;&lt;p&gt;إذا كانت الإجابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;نعم
&lt;/pre&gt;&lt;p&gt;يمكن استخدام Public Storage.&lt;/p&gt;&lt;p&gt;أما إذا كانت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;لا
&lt;/pre&gt;&lt;p&gt;فاستخدم تخزينًا خاصًا وآلية Authorization مناسبة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;اربط Storage مع Database&lt;/b&gt;&lt;/p&gt;&lt;p&gt;عندما يكون الملف مرتبطًا بسجل معين، خزّن مساره في Model.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.image
users.avatar
documents.file
&lt;/pre&gt;&lt;p&gt;هذا يجعل إدارة الملفات أسهل.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;لا تثق ببيانات المستخدم&lt;/b&gt;&lt;/p&gt;&lt;p&gt;اسم الملف والامتداد والمحتوى كلها بيانات قادمة من المستخدم.&lt;/p&gt;&lt;p&gt;يجب التعامل معها بحذر واستخدام Validation مناسب.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;تمرين عملي&lt;/b&gt;&lt;/p&gt;&lt;p&gt;حان الآن دورك لتطبيق ما تعلمته.&lt;/p&gt;&lt;p&gt;أنشئ نظامًا لإضافة المقالات يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Title
Content
Featured Image&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الأولى&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أضف عمودًا إلى جدول &lt;code inline=""&gt;articles&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;image
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الثانية&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ Form يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
content
image
&lt;/pre&gt;&lt;p&gt;واستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;multipart/form-data
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الثالثة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تحقق من الصورة باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'image' =&amp;gt; [
    'required',
    'image',
    'max:2048',
]
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الرابعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;خزن الصورة في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public/articles
&lt;/pre&gt;&lt;p&gt;باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;file('image')-&amp;gt;store(
    'articles',
    'public'
);
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الخامسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;احفظ المسار الناتج في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.image
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة السادسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan storage:link
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة السابعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اعرض الصورة داخل صفحة المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;img
    src="{{ Storage::url($article-&amp;gt;image) }}"
    alt="{{ $article-&amp;gt;title }}"
&amp;gt;
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الثامنة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أضف ميزة تعديل المقال بحيث يمكن للمستخدم استبدال الصورة.&lt;/p&gt;&lt;p&gt;عند رفع صورة جديدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;New Image
 ↓
Store
 ↓
Delete Old Image
 ↓
Update Database
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة التاسعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أضف زر حذف المقال، وتأكد من حذف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Database Record
+
Image File
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة العاشرة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اجعل المقالات مرتبطة بالمستخدم الحالي، بحيث لا يستطيع المستخدم تعديل أو حذف مقال مستخدم آخر.&lt;/p&gt;&lt;p&gt;وهنا يمكنك الاستفادة من الدرس الثالث عشر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
+
Authorization
+
Storage
&lt;/pre&gt;&lt;p&gt;وبذلك تكون قد ربطت عدة مفاهيم تعلمتها في الدروس السابقة داخل تطبيق واحد.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ماذا تعلمنا في هذا الدرس؟&lt;/h3&gt;&lt;p&gt;في هذا الدرس تعلمنا كيفية التعامل مع الملفات والصور في Laravel.&lt;/p&gt;&lt;p&gt;تعلمنا:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;مفهوم File Storage.&lt;/li&gt;&lt;li&gt;مفهوم Filesystem.&lt;/li&gt;&lt;li&gt;ما هو Disk.&lt;/li&gt;&lt;li&gt;Local Disk.&lt;/li&gt;&lt;li&gt;Public Disk.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;config/filesystems.php&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;storage/app&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;storage/app/public&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;public/storage&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;php artisan storage:link&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;رفع الملفات من HTML Forms.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;multipart/form-data&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;$request-&amp;gt;file()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;hasFile()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Validation للملفات.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;image&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;file&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;mimes&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;mimetypes&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;max&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;dimensions&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;File::image()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;store()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;storeAs()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Storage::put()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Storage::putFile()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Storage::url()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;حذف الملفات باستخدام &lt;code inline=""&gt;Storage::delete()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;استبدال الملفات القديمة.&lt;/li&gt;&lt;li&gt;تخزين مسار الملف في Database.&lt;/li&gt;&lt;li&gt;الفرق بين Public وPrivate Storage.&lt;/li&gt;&lt;li&gt;Temporary URLs.&lt;/li&gt;&lt;li&gt;معالجة الصور في Laravel 13.&lt;/li&gt;&lt;li&gt;ربط Storage مع Models.&lt;/li&gt;&lt;li&gt;بناء نظام رفع صورة كامل.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;أصبح لدينا الآن تصور واضح عن طريقة تعامل Laravel مع الملفات.&lt;/p&gt;&lt;p&gt;يمكن تلخيص العملية الأساسية بهذا الشكل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
Upload Form
 ↓
HTTP Request
 ↓
Validation
 ↓
File Storage
 ↓
File Path
 ↓
Database
 ↓
Storage::url()
 ↓
Display File
&lt;/pre&gt;&lt;p&gt;وعند تحديث الملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Old File
 ↓
New Upload
 ↓
Validation
 ↓
Store New File
 ↓
Delete Old File
 ↓
Update Database
&lt;/pre&gt;&lt;p&gt;ومن أهم الأشياء التي يجب أن تتذكرها في هذا الدرس أن Laravel لا يجبرك على ربط تطبيقك بنظام تخزين واحد. يمكنك استخدام التخزين المحلي أثناء التطوير، ثم الانتقال إلى تخزين سحابي مثل S3 عند الحاجة، مع الاحتفاظ بنفس فكرة التعامل مع الملفات عبر Storage API.&lt;/p&gt;&lt;p&gt;كما تعلمنا أن &lt;strong&gt;Validation وAuthorization وStorage&lt;/strong&gt; تعمل معًا.&lt;/p&gt;&lt;p&gt;فمثلًا عند رفع صورة مقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
 ↓
هل المستخدم مسجل الدخول؟
 ↓
Authorization
 ↓
هل يستطيع تعديل المقال؟
 ↓
Validation
 ↓
هل الملف صورة وحجمه مناسب؟
 ↓
Storage
 ↓
تخزين الملف
 ↓
Database
 ↓
حفظ المسار
&lt;/pre&gt;&lt;p&gt;وهذه الطريقة هي التي تساعدك على بناء تطبيقات Laravel أكثر تنظيمًا وأمانًا وقابلية للتوسع.&lt;/p&gt;&lt;p&gt;في الدرس القادم سننتقل إلى موضوع مهم جدًا بعد التعامل مع الملفات، وهو &lt;strong&gt;Pagination وFiltering وSearching في Laravel&lt;/strong&gt;، وسنتعلم كيف نعرض كميات كبيرة من البيانات بطريقة منظمة، مع تقسيم النتائج إلى صفحات وإضافة البحث والتصفية والترتيب إلى قوائم المقالات.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/895737409686910627/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/laravel-file-storage-upload-files.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/895737409686910627" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/895737409686910627" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/laravel-file-storage-upload-files.html" rel="alternate" title="رفع الصور والملفات وتخزينها وعرضها File Storage في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwudbSR5mpaYigO1GPGij7Qy4U52_gSB4V_d0wGJGGLd2lZ0HD2p_kqGMU1UDPSstS02vIbjOtChlWTGLQfR4ZmpabHojGex4c57qKx4Jo6KfbdV-5AfD3rdPihz5E0DJlOAB7KHUkSjquyzlWNBU0Flz0JaZetGXqTLA6rWmrpAcAyldPssHTTsdE04Ak/s72-c/imageedit_1_6314910003.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-5330741115300220944</id><published>2026-10-08T12:04:33.342+03:00</published><updated>2026-10-08T12:04:33.342+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">أفضل 7 أدوات ذكاء اصطناعي للمبرمجين</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiNpxNzezVB4UHP6m23dUDLE58m5cNW2A5QKznpTq7ZEvToFieXJRhLjypj543Wu6fsv2_DlqbTklbgHfXquqYGw8CigVtt2XFv12UEQrJVbjWNsWf7MABrreksnatuhtHUFX3sc81n629DJBb7NKIXOeKMDlhzZY3RiUAsjzsNkkVzBVUHHvCtkpjRy4V/s640/imageedit_1_9846749514.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="أفضل 7 أدوات ذكاء اصطناعي للمبرمجين" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiNpxNzezVB4UHP6m23dUDLE58m5cNW2A5QKznpTq7ZEvToFieXJRhLjypj543Wu6fsv2_DlqbTklbgHfXquqYGw8CigVtt2XFv12UEQrJVbjWNsWf7MABrreksnatuhtHUFX3sc81n629DJBb7NKIXOeKMDlhzZY3RiUAsjzsNkkVzBVUHHvCtkpjRy4V/s1600/imageedit_1_9846749514.webp" title="أفضل 7 أدوات ذكاء اصطناعي للمبرمجين" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;كيف تضاعف سرعتك في كتابة وتصحيح الكود؟&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;لم يعد &lt;a href="https://www.nusurtech.ca/2026/08/fifteen-ai-tools-from-google.html"&gt;الذكاء الاصطناعي&lt;/a&gt; التوليدي مجرد أداة ثانوية لمساعدة المطورين أو كتابة بعض السطور الروتينية، بل تحول إلى رفيق أساسي وطرف في عملية التطوير (Pair Programmer). أصبح الاعتماد على أدوات الذكاء الاصطناعي الفرق الجوهري بين مبرمج يقضي أياماً في بناء واجهة وتصحيح أخطائها، ومبرمج آخر ينجز نفس المهمة في بضع ساعات بإنتاجية مضاعفة وكود كفؤ ونظيف.&lt;/p&gt;&lt;p&gt;في هذا الدليل الشامل على موقع نسور التقنية، نستعرض أفضل 7 أدوات ذكاء اصطناعي للمبرمجين، ونحلل نقاط قوتها، وكيف يمكنك استغلالها لتسريع كتابة الكود، واكتشاف الثغرات، وتسهيل عملية تصحيح الأخطاء (Debugging).&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;1. محرر Cursor AI: أفضل بيئة تطوير متكاملة مدعومة بالذكاء الاصطناعي&lt;/h3&gt;&lt;p&gt;يُعد &lt;a href="https://www.nusurtech.ca/2026/10/cursor-ai-developer-guide.html"&gt;Cursor AI&lt;/a&gt; خياراً بارزاً ومفضلاً لدى العديد من المطورين حالياً. هو ليس مجرد إضافة (Plugin) تُثبت على المحرر، بل هو محرر كود متكامل تم بناؤه استناداً إلى نواة VS Code.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;أهم مميزات Cursor AI&lt;/h4&gt;&lt;p&gt;&lt;b&gt;فهم سياق المشروع بالكامل (Codebase Indexing)&lt;/b&gt;: يستطيع Cursor مسح جميع ملفات المشروع ومعرفة العلاقات بين الملفات والقواعد البرمجية بفضل الرموز المخصصة مثل @Codebase و@Files.&lt;/p&gt;&lt;p&gt;&lt;b&gt;التعديل متعدد الملفات (Composer)&lt;/b&gt;: يتيح تنفيذ تعديل سيناريو برمجي كامل يمتد عبر أكثر من ملف بضغطة زر واحدة والتأكد من توافق التغييرات.&lt;/p&gt;&lt;p&gt;&lt;b&gt;التصحيح المباشر (Auto-Debugging)&lt;/b&gt;: يقرأ الأخطاء من الـ Terminal ويقترح التعديل المناسب فوراً داخل الكود.&lt;/p&gt;&lt;p&gt;إذا كنت تبحث عن بيئة عمل توفر عليك البحث والنسخ واللصق، وتتيح التبديل بين النماذج الذكية المتطورة (مثل Claude 3.5 Sonnet وGPT-4o) بداخل المحرر مباشرة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;2. GitHub Copilot: رفيق البرمجة الأكثر انتشاراً واستقراراً&lt;/h3&gt;&lt;p&gt;يظل &lt;b&gt;GitHub Copilot&lt;/b&gt;، المطور بالشراكة بين GitHub وOpenAI، أحد أكثر المساعدات البرمجية موثوقية وانتشاراً حول العالم.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;أهم مميزات&amp;nbsp;GitHub Copilot&lt;/h4&gt;&lt;p&gt;&lt;b&gt;التكامل الشامل مع بيئات التطوير&lt;/b&gt;: يعمل بسلاسة كإضافة على VS Code, JetBrains IDEs, Neovim, وVisual Studio.&lt;/p&gt;&lt;p&gt;&lt;b&gt;الإكمال التلقائي الذكي (Smart Autocomplete)&lt;/b&gt;: يتعلم أسلوب كتابتك ويوفر اقتراحات فورية ودقيقة للسطور أو الدوال أثناء الكتابة.&lt;/p&gt;&lt;p&gt;&lt;b&gt;خاصية Copilot Chat&lt;/b&gt;: تتيح لك مناقشة مشروعك، طلب شرح لدالة معينة، أو كتابة اختبارات الوحدات (Unit Tests).&lt;/p&gt;&lt;p&gt;إذا كنت تفضل البقاء داخل بيئة التطوير الحالية الخاصة بك دون التخلي عن إضافاتك، مع الحصول على إكمال تلقائي سريع مستمر أثناء كتابة الكود.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;3. Claude Code: قوة معالجة المشاريع الضخمة عبر Terminal&lt;/h3&gt;&lt;p&gt;تُعتبر &lt;b&gt;Claude Code&lt;/b&gt; (الأداة الموجهة للمطورين من شركة Anthropic) من أحدث وأقوى الأدوات القائمة على الواجهة النصية (CLI).&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;مميزات Claude Code&lt;/h4&gt;&lt;p&gt;نافذة سياق ضخمة (1 Million Tokens): قادرة على استيعاب وقراءة مشاريع كاملة تحتوي على آلاف الأسطر في جلسة واحدة دون التضحية بالدقة.&lt;/p&gt;&lt;p&gt;منطق تفكير تسلسلي (Step-by-Step Reasoning): تقوم الأداة بتفكيك المهام البرمجية إلى خطوات ومراحل قبل البدء بالتنفيذ لتفادي الأخطاء.&lt;/p&gt;&lt;p&gt;أداة موجهة للـ Terminal: تتيح إدارة وتنفيذ أوامر Shell وقراءة ملفات Git بشكل مباشر.&lt;/p&gt;&lt;p&gt;ممتازة للمطورين المحترفين الذين يقضون معظم وقتهم في الـ Terminal أو يتعاملون مع مشاريع برمجية واسعة النطاق تتطلب فهم الهيكلية المعقدة (Legacy Codebases).&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;4. Codeium: البديل المجاني القوي والأسرع أدائاً&lt;/h3&gt;&lt;p&gt;إذا كنت تبحث عن أداة ذكاء اصطناعي مجانية للأفراد تقدم أداءً يقارن بالأدوات المدفوعة، فإن &lt;b&gt;Codeium &lt;/b&gt;هي خيار مناسب.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;مميزات Codeium&lt;/h4&gt;&lt;p&gt;&lt;b&gt;خطة مجانية للأفراد&lt;/b&gt;: توفر إكمالاً تلقائياً للأكواد وشات ذكي دون قيود مجحفة على الاستخدام المباشر.&lt;/p&gt;&lt;p&gt;&lt;b&gt;دعم لأكثر من 70 لغة برمجة&lt;/b&gt;: متوافقة مع أطياف واسعة من لغات التطوير وتدعم أكثر من 40 محرر كود.&lt;/p&gt;&lt;p&gt;&lt;b&gt;سرعة فائقة (Low Latency)&lt;/b&gt;: تتميز بنماذج سريعة الاستجابة توفر التنبؤ بالكود دون تعليق أو بطء داخل المحرر.&lt;/p&gt;&lt;p&gt;الخيار الأمثل للمبتدئين والطلاب والمطورين الذين يريدون تقليل التكاليف دون التنازل عن جودة المساعد البرمجي.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;5. v0 by Vercel: ثورة في توليد واجهات المستخدم (Front-End)&lt;/h3&gt;&lt;p&gt;تُعد أداة &lt;b&gt;v0&lt;/b&gt; المبتكرة من شركة Vercel حلاً ممتازاً لمطوري الواجهات الأمامية ومطوري Full-Stack الذين يرغبون في بناء واجهات وتطبيقات React وTailwind CSS في ثوانٍ معدودة.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;مميزات&amp;nbsp;v0 by Vercel&lt;/h4&gt;&lt;p&gt;تحويل الوصف أو الصور إلى واجهات تفاعلية: بمجرد كتابة توجيه (Prompt) أو رفع تصميم، تقوم الأداة بتوليد كود React كفؤ ومصمم بـ Tailwind CSS.&lt;/p&gt;&lt;p&gt;معاينة حية ومباشرة (Live Preview): يمكنك معاينة الواجهة والتعديل عليها فورياً قبل نسخ الكود ونقله إلى مشروعك.&lt;/p&gt;&lt;p&gt;مكونات نظيفة وقابلة للتعديل: تعتمد الأداة على مكونات مكتبات حديثة مثل shadcn/ui وتنتج كوداً منظمًا للغاية.&lt;/p&gt;&lt;p&gt;ممتازة عند البدء في بناء النماذج الأولية (Prototypes)، أو عند الحاجة لتسريع تطوير الواجهات المعقدة واستغلال الوقت لبناء المنطق الخلفي (Back-End).&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;6. Tabnine: خيار المؤسسات والأمان العالي (Privacy-First)&lt;/h3&gt;&lt;p&gt;للشركات والمطورين الذين يعملون على مشاريع حساسّة تُمنع فيها مشاركة الأكواد أو رفعها على سيرفرات خارجية، توفر أداة &lt;b&gt;Tabnine&lt;/b&gt; حلاً آمناً.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;مميزات&amp;nbsp;Tabnine&lt;/h4&gt;&lt;p&gt;&lt;b&gt;خاصية الاستضافة المحلية (On-Premises / Air-Gapped)&lt;/b&gt;: تتيح تشغيل النماذج داخل سيرفرات الشركة الخاصة بدون إرسال البيانات للخارج.&lt;/p&gt;&lt;p&gt;&lt;b&gt;عدم حفظ أو تدريب البيانات (Zero Retention)&lt;/b&gt;: تضمن عدم استغلال الكود الخاص بك لتدريب نماذج الذكاء الاصطناعي العامة.&lt;/p&gt;&lt;p&gt;&lt;b&gt;التوافق التام مع قوانين الملكية الفكرية&lt;/b&gt;: تضمن استخدام أكواد خالية من مشاكل التراخيص مفتوحة المصدر.&lt;/p&gt;&lt;p&gt;الخيار الأول للفرق والشركات المؤسسية (Enterprise) ومشاريع القطاعات المالية أو الحسابية الحساسة التي تفرض سياسات صارمة على خصوصية البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;7. Amazon Q Developer: المساعد الأفضل لمطبقي خدمات AWS&lt;/h3&gt;&lt;p&gt;إذا كنت تبني تطبيقاتك وتعتمد بشكل رئيسي على خدمات Amazon Web Services (AWS)، فإن &lt;b&gt;Amazon Q Developer&lt;/b&gt; (المعروفة سابقاً بـ CodeWhisperer) توفر تكاملاً مخصصاً.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;مميزات Amazon Q Developer&lt;/h4&gt;&lt;p&gt;فهم عميق لبنية AWS: توليد أكواد وتكوينات أمنية مخصصة لخدمات مثل S3, Lambda, وDynamoDB وفقاً لأفضل الممارسات.&lt;/p&gt;&lt;p&gt;فحص الثغرات الأمنية (Security Scanning): فحص الكود واكتشاف الثغرات وتوفير حلول لمعالجتها مجاناً في حدود الاستخدام.&lt;/p&gt;&lt;p&gt;دعم التحويل الذاتي للكود (Code Transformation): المساعدة في تحديث وتحديث نسخة المشاريع القديمة (مثل ترقية إصدارات Java).&lt;/p&gt;&lt;p&gt;إذا كانت بنيتك التحتية وتطبيقاتك تعتمد بشكل أساسي على منظومة AWS Cloud.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;مقارنة سريعة بين أفضل أدوات الذكاء الاصطناعي للمبرمجين&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;Cursor&lt;/b&gt; : أبرز حَالَة استخدام هي&amp;nbsp;مشاريع متعددة الملفات وسياق شامل و السعر (تقريبي) هو خطة مجانية / Pro بـ 20$/شهرياً وبالنسبة لدعم البيئات (IDE/CLI) محرر قائم بذاته (VS Code Fork).&lt;/li&gt;&lt;li&gt;&lt;b&gt;GitHub Copilot&lt;/b&gt; : أبرز حَالَة استخدام هي البرمجة الزوجية والسرعة داخل المحرر و السعر (تقريبي) هو خطة مدفوعة تبدأ من 10$/شهرياً وبالنسبة لدعم البيئات (IDE/CLI) إضافة تعمل مع أغلب المحررات.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Claude Code&lt;/b&gt; : أبرز حَالَة استخدام هي سياق ضخم وعمل من الـ Terminal و السعر (تقريبي) هو يعتمد على خطة Claude Pro / API وبالنسبة لدعم البيئات (IDE/CLI) CLI / Terminal.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Codeium&lt;/b&gt;: أبرز حَالَة استخدام هي الأداة المجانية الأكثر شمولاً و السعر (تقريبي) هو خطة مجانية مجزية للأفراد وبالنسبة لدعم البيئات (IDE/CLI) أكثر من 40 محرر كود.&lt;/li&gt;&lt;li&gt;&lt;b&gt;v0 by Vercel&lt;/b&gt; : أبرز حَالَة استخدام هي&amp;nbsp;التوليد السريع لواجهات المستخدم (UI) و السعر (تقريبي) هو خطة مجانية بسيطة / مدفوع وبالنسبة لدعم البيئات (IDE/CLI) متصفح / تطبيق ويب.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Tabnine&lt;/b&gt; : أبرز حَالَة استخدام هي أمان البيانات والخصوصية المرتفعة و السعر (تقريبي) هو خطة مدفوعة للمؤسسات والأفراد وبالنسبة لدعم البيئات (IDE/CLI) أجهزة محلية ومختلف المحررات.&lt;/li&gt;&lt;li&gt;&lt;b&gt;Amazon Q&lt;/b&gt; : أبرز حَالَة استخدام هي المطورون في بيئة AWS Cloud و السعر (تقريبي) هو خطة مجانية محددة / Pro بـ 19$/شهرياً وبالنسبة لدعم البيئات (IDE/CLI) VS Code, JetBrains &amp;amp; AWS CLI.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;نصائح عملية لمضاعفة سرعتك وتجنب أخطاء AI البرمجية&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;اكتب توجيهات (Prompts) واضحة ومحددة&lt;/b&gt;: حدد الإطار المستخدم، والنتيجة المتوقعة، والقيود (مثل التوافق مع إصدار معالج معين أو تجنب مكتبة قديمة).&lt;/li&gt;&lt;li&gt;&lt;b&gt;فحص الكود (Code Review) خطوة أساسية&lt;/b&gt;: لا تقوم بدمج (Merge) أي كود مولد دون فهمه وتجربته، حيث قد يحتوي الكود المولد على ثغرات منطقية أو مكتبات غير آمنة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;اكتب اختبارات تلقائية (Unit Tests)&lt;/b&gt;: استخدم الذكاء الاصطناعي لكتابة اختبارات تغطي الحالات الاستثنائية (Edge Cases) لضمان عدم كسر النظام أثناء إعادة الهيكلة.&lt;/li&gt;&lt;li&gt;&lt;b&gt;دمج أكثر من أداة حسب الحاجة&lt;/b&gt;: استخدام أداة مثل v0 لبناء الواجهة، وCursor للتطوير وتوسيع منطق العمل، يمنحك سرعة قياسية في التنفيذ.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;تقنيات الذكاء الاصطناعي المخصصة للبرمجة أضحت مهارة أساسية للمطور العصر. اختيار الأداة المناسبة يعتمد على نوع مشاريعك، متطلبات الأمان لديك، الميزانية، وبيئة العمل التي تفضلها. البداية بتجربة الأدوات المتاحة ستتيح لك رفع كفاءة كودك وتوفير ساعات طويلة من العمل الروتيني.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/5330741115300220944/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/best-ai-tools-for-developers.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5330741115300220944" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5330741115300220944" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/best-ai-tools-for-developers.html" rel="alternate" title="أفضل 7 أدوات ذكاء اصطناعي للمبرمجين" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiNpxNzezVB4UHP6m23dUDLE58m5cNW2A5QKznpTq7ZEvToFieXJRhLjypj543Wu6fsv2_DlqbTklbgHfXquqYGw8CigVtt2XFv12UEQrJVbjWNsWf7MABrreksnatuhtHUFX3sc81n629DJBb7NKIXOeKMDlhzZY3RiUAsjzsNkkVzBVUHHvCtkpjRy4V/s72-c/imageedit_1_9846749514.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-3935162973325046280</id><published>2026-10-07T11:09:38.132+03:00</published><updated>2026-10-07T11:09:38.132+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">دليل استخدام Cursor AI ثورة في كتابة الكود وتسريع التطوير</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHPnkJAXr1MZBV3U9BPo0zE_PEiOY71jqmiVpGjMZ8CWKNgvn4K2z5vP7W5yxoiFnyYXmLH31GDsIbe0Cn3gAtsfTTmWqrKobmwH45zFyrBCaotZLrCUyOHaPdtu_E5Koc2GHqxrLu9fBxHNi-HMPMZ7eFqdAq-ARvOIvteyYXI9Z2pMNxeZkZfUVLDf37/s640/imageedit_1_2152645285.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="دليل استخدام Cursor AI: كيف تحدث هذه أداة ثورة في كتابة الكود وتسريع التطوير؟" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHPnkJAXr1MZBV3U9BPo0zE_PEiOY71jqmiVpGjMZ8CWKNgvn4K2z5vP7W5yxoiFnyYXmLH31GDsIbe0Cn3gAtsfTTmWqrKobmwH45zFyrBCaotZLrCUyOHaPdtu_E5Koc2GHqxrLu9fBxHNi-HMPMZ7eFqdAq-ARvOIvteyYXI9Z2pMNxeZkZfUVLDf37/s1600/imageedit_1_2152645285.webp" title="دليل استخدام Cursor AI: كيف تحدث هذه أداة ثورة في كتابة الكود وتسريع التطوير؟" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;دليل استخدام Cursor AI&lt;/h3&gt;&lt;p&gt;شهد عالم تطوير البرمجيات في السنوات الأخيرة تحولاً جذرياً بفضل تقنيات &lt;a href="https://www.nusurtech.ca/2026/08/fifteen-ai-tools-from-google.html"&gt;الذكاء الاصطناعي&lt;/a&gt; التوليدي. وبينما اعتاد المطورون على استخدام المساعدات البرمجية التقليدية والمكونات الإضافية (Plugins) داخل محركات الكود، جاء محرر النصوص &lt;b&gt;Cursor AI&lt;/b&gt; ليغير قواعد اللعبة بالكامل.&lt;/p&gt;&lt;p&gt;محرر &lt;b&gt;Cursor&lt;/b&gt; ليس مجرد إضافة تُثبّت على برامج أخرى، بل هو &lt;a href="https://www.nusurtech.ca/2024/04/code-editor.html"&gt;محرر كود&lt;/a&gt; متكامل مبني خصيصاً ليجعل الذكاء الاصطناعي &lt;a href="https://www.nusurtech.ca/2026/09/best-ai-tools-excel-csv.html"&gt;AI&lt;/a&gt; جزءاً أساسياً من بيئة التطوير الخاصة بك. في هذا الدليل الشامل على موقع &lt;b&gt;&lt;a href="https://www.nusurtech.ca/2026/08/how-to-search-for-jobs-using-artificial-intelligences.html"&gt;نسور التقنية&lt;/a&gt;&lt;/b&gt;، سنغوص في أعماق أداة &lt;b&gt;Cursor AI&lt;/b&gt;، ونكتشف كيف يمكنك استغلالها لتضاعف سرعتك وانتاجيتك في كتابة وتطوير البرمجيات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو محرر Cursor AI وكيف يعمل؟&lt;/h3&gt;&lt;p&gt;&lt;b&gt;Cursor AI&lt;/b&gt; هو محرر كود مفتوح المصدر تم إنشاؤه بناءً على نواتج محرر &lt;b&gt;&lt;a href="https://www.nusurtech.ca/2023/12/best-5-code-editors-for-windows.html"&gt;VS Code&lt;/a&gt;&lt;/b&gt; الشهير (Fork of VS Code). يعني ذلك أنك إذا كنت تستخدم VS Code، ستشعر ببيئة عمل مألوفة جداً دون أي منحنى تعلم صعب؛ حيث يمكنك نقل كافة اختصاراتك، إضافاتك، وإعداداتك بضغطة زر واحدة.&lt;/p&gt;&lt;p&gt;الفرق الجوهري يكمن في أن Cursor ليس مجرد محرر نصوص أُضيفت له واجهة دردشة شات، بل صُمم ليصل الذكاء الاصطناعي ببيئة مشروعك بالكامل (Codebase-Aware AI). يستوعب المحرر سياق المشروع، وهيكلية الملفات، والعلاقات بين الكائنات (Classes) والدوال (Functions)، مما يجعله قادراً على اقتراح حلول دقيقة وشاملة وتعديل الملفات المتعددة تلقائياً.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أبرز المميزات التي تجعل Cursor يعلو على المنافسين&lt;/h3&gt;&lt;p&gt;توجد العديد من أدوات الذكاء الاصطناعي الموجهة للمبرمجين مثل GitHub Copilot وChatGPT، لكن Cursor يتفوق بفارق شاسع في تجربة المطور بسبب الميزات التالية:&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;أ) فهم سياق المشروع بالكامل (Context Awareness &amp;amp; @ Symbols)&lt;/h4&gt;&lt;p&gt;واحدة من أقوى ميزات Cursor هي قدرتك على إمداد نموذج الذكاء الاصطناعي بالسياق المناسب باستخدام الرمز @:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;@Files: لإشارة إلى ملف معين داخل المشروع ليركز النموذج عليه.&lt;/li&gt;&lt;li&gt;@Codebase: لإجبار النموذج على مسح وفحص كامل المشروع لبناء إجابات واقتراحات تتوافق مع هيكلية العمل الحالية.&lt;/li&gt;&lt;li&gt;@Docs: لربط المحرر بالمكتبات الخارجية وثائقها الرسمية (مثل وثائق Laravel، React، أو Tailwind CSS)، ليولد لك أكواداً وفقاً لآخر التحديثات وتجنب الأكواد القديمة (Deprecated Code).&lt;/li&gt;&lt;li&gt;@Git: للتحقق من التغييرات الأخيرة أو التعديلات المرتكبة على مستودع الكود.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ب) التعديل متعدد الملفات (Composer / Multi-File Editing)&lt;/h4&gt;&lt;p&gt;باستخدام أداة &lt;b&gt;Composer&lt;/b&gt; (التي تُفعل عبر الاختصار Ctrl + I أو Cmd + I)، يمكنك طلب إجراء تعديل يمتد عبر عدة ملفات في المشروع في وقت واحد. على سبيل المثال، يمكنك أن تطلب: "قم بإنشاء نموذج جديد باسم Product وخطة Migration في قاعدة البيانات مع الربط في Route"، وسيقوم Cursor بإنشاء والتعديل على جميع الملفات المطلوبة وتطبيق التغييرات تلقائياً.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ج) الإكمال التلقائي الذكي (Cursor Tab)&lt;/h4&gt;&lt;p&gt;يتجاوز الإكمال التلقائي في Cursor مجرد تخمين الكلمة التالية. فهو يستنزف نماذج فائقة السرعة للتنبؤ بسلسلة من السطور المترابطة أو إكمال التعديلات الشائعة، ويمكنك قبول الاقتراح فوراً بالضغط على زر Tab.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;د) تصحيح الأخطاء التلقائي (Auto-Debugging)&lt;/h4&gt;&lt;p&gt;عند ظهور خطأ أثناء تشغيل مشروعك في Terminal، يوفر Cursor زراً مخصصاً لإصلاح الخطأ تلقائياً (Fix with AI). يحلل المحرر رسالة الخطأ والسطور المؤدية له، ويقترح التعديل المباشر لحل المشكلة فوراً.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;خطوة بخطوة: كيفية تثبيت وإعداد Cursor AI&lt;/h3&gt;&lt;p&gt;لتستمتع بتجربة تطوير استثنائية على موقعك أو مشروعك، اتبع خطوات الإعداد التالية:&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة 1: التحميل والتثبيت&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;اذهب إلى الموقع الرسمي للمحرر cursor.com.&lt;/li&gt;&lt;li&gt;حمل النسخة المتوافقة مع نظام تشغيلك (Windows, macOS, أو Linux).&lt;/li&gt;&lt;li&gt;قم بتثبيت البرنامج مثل أي تطبيق عادي.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة 2: استيراد إعدادات VS Code&lt;/h4&gt;&lt;p&gt;عند تشغيل Cursor لأول مرة، سيطلب منك البرنامج إذا كنت ترغب في استيراد إضافاتك وثيماتك واختصاراتك من VS Code. اختر Import لتبدأ فوراً بنفس البيئة التي اعتادت عليها أصابعك.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;الخطوة 3: ضبط نماذج الذكاء الاصطناعي (AI Models)&lt;/h4&gt;&lt;p&gt;يدعم Cursor عدة نماذج ذكاء اصطناعي رائدة، مثل:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;Claude 3.5 Sonnet: النموذج الأفضل بلا منافس في كتابة الكود وفهم السياق البرمجي.&lt;/li&gt;&lt;li&gt;GPT-4o: نموذج سريع وممتاز في مهام الشرح والتحليل.&lt;/li&gt;&lt;li&gt;Cursor-Small: نموذج فائق السرعة ومناسب للإكمال السريع تلقائياً.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكنك التبديل بين النماذج بسهولة من خانة الإعدادات (Settings &amp;gt; AI) أو أثناء الدردشة داخل المحرر.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الممارسات العملية لتنفيذ مختلف المهام البرمجية باستخدام Cursor&lt;/h3&gt;&lt;p&gt;ولكي تحقق أقصى استفادة من المحرر في مشاريعك اليومية، إليك الأسلوب العملي والأوامر المناسبة لمختلف الحالات:&lt;/p&gt;&lt;p&gt;أولاً: توليد ميزات جديدة (Feature Generation)&lt;/p&gt;&lt;p&gt;افتتاح نافذة الدردشة بواسطة Ctrl + L (أو Cmd + L) واكتب توجيهاً واضحاً ومحدداً.&lt;/p&gt;&lt;p&gt;مثال توجيه (Prompt):&lt;/p&gt;&lt;p&gt;"أريد إنشاء واجهة برمجة تطبيقات (API Endpoint) بـ Laravel لإضافة منتج جديد. استخدم @StoreProductRequest للتحقق من البيانات، واضمن إعادة الاستجابة بتنسيق JSON مع كود الحالة 201."&lt;/p&gt;&lt;p&gt;ثانياً: إعادة هيكلة الكود وتصحيحه (Refactoring &amp;amp; Bug Fixing)&lt;/p&gt;&lt;p&gt;قم بتحديد الكود المطلوب في المحرر، ثم اضغط على Ctrl + K (أو Cmd + K) لتظهر لك نافذة التعديل المباشر (In-line Edit).&lt;/p&gt;&lt;p&gt;مثال توجيه:&lt;/p&gt;&lt;p&gt;"أعد كتابة هذه الدالة لتتبع مبدأ المسؤولية الأحادية (Single Responsibility Principle) وقم بتحسين أداء الاستعلام للحد من مشكلة N+1."&lt;/p&gt;&lt;p&gt;ثالثاً: التوثيق واختبارات الوحدات (Documentation &amp;amp; Unit Testing)&lt;/p&gt;&lt;p&gt;يمكنك استخدام الكود المكتوب لتوليد الاختبارات والتوثيق تلقائياً بنفس الأسلوب:&lt;/p&gt;&lt;p&gt;"اكتب اختبارات وحدة (Unit Tests) باستخدام PEST PHP لهذه الدالة مع تغطية جميع الحالات الاستثنائية (Edge Cases)."&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;مقارنة شائعة: Cursor AI أم الأدوات الأخرى؟&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;إن&amp;nbsp;Cursor AI&amp;nbsp;ممتاز وعميق (@Codebase) و&amp;nbsp;التعديل متعدد الملفات مدعوم بقوة (Composer) و&amp;nbsp;مدعوم (@Docs) و&amp;nbsp;السرعة والاندماج محرر قائم بذاته ممتازة.&lt;/li&gt;&lt;li&gt;ان&amp;nbsp;GitHub Copilot&amp;nbsp;محدود بمجموع الملفات المفتوحة والتعديل متعدد الملفات&amp;nbsp;غير مدعوم بشكل كامل و&amp;nbsp;غير مدعوم و&amp;nbsp;السرعة والاندماج إضافة تجعل الأداء أبطأ أحياناً.&lt;/li&gt;&lt;li&gt;ان&amp;nbsp;ChatGPT / Web AI&amp;nbsp;معدوم (تعتمد على النسخ واللصق) والتعديل متعدد الملفات&amp;nbsp;غير مدعوم و&amp;nbsp;محدد ببيانات التدريب والسرعة والاندماج&amp;nbsp;خارج بيئة التطوير&lt;/li&gt;&lt;/ol&gt;&lt;h3 style="text-align: right;"&gt;نصائح ذهبية للمطورين لاحتراف Cursor AI&lt;/h3&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;لا تعتمد على الذكاء الاصطناعي بشكل عمياء: افحص دائماً الكود الناتج (Code Review). الذكاء الاصطناعي يسرّع الإنتاجية ولكنه ليس بديلاً عن مراجعة الفكر والتأكد من أمان الكود.&lt;/li&gt;&lt;li&gt;استغل ملف .cursorrules: يمكنك إضافة ملف في جذر مشروعك باسم .cursorrules وتكتب فيه القواعد المعيارية لمشروعك (مثلاً: "استخدم دائماً التسميات بصيغة CamelCase"، أو "اكتب الكود باستخدما إطار &lt;a href="https://www.nusurtech.ca/2026/09/laravel-factories-seeders-faker.html"&gt;Laravel 11&lt;/a&gt; وتجنب الأساليب القديمة"). سيلتزم المحرر بهذه التعليمات طوال العمل على المشروع.&lt;/li&gt;&lt;li&gt;أطعم المحرر بالتوثيق الحديث: إذا كنت تعمل بمكتبة جديدة أو إطار عمل تم تحديثه مؤخراً، استخدم @Docs وأضف رابط التوثيق ليتعلم المحرر الأساليب الحديثة فوراً.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لم يعد الذكاء الاصطناعي مجرد أداة ثانوية لمساعدة المطورين، بل أصبح حجر الزاوية في زيادة الإنتاجية وتحسين جودة البرمجيات. يُعد محرر Cursor AI الخطوة المستقبليّة الطبيعية لبيئات التطوير، حيث يختصر عليك ساعات طويلة من البحث والمهام الروتينية ليركز فكرك على ابتكار الحلول وتصميم البنيات البرمجية القوية.&lt;/p&gt;&lt;p&gt;جرب Cursor AI اليوم في مشروعك القادم، وستلاحظ بنفسك الفارق الهائل في السرعة وسلاسة العمل!&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/3935162973325046280/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/cursor-ai-developer-guide.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/3935162973325046280" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/3935162973325046280" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/cursor-ai-developer-guide.html" rel="alternate" title="دليل استخدام Cursor AI ثورة في كتابة الكود وتسريع التطوير" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHPnkJAXr1MZBV3U9BPo0zE_PEiOY71jqmiVpGjMZ8CWKNgvn4K2z5vP7W5yxoiFnyYXmLH31GDsIbe0Cn3gAtsfTTmWqrKobmwH45zFyrBCaotZLrCUyOHaPdtu_E5Koc2GHqxrLu9fBxHNi-HMPMZ7eFqdAq-ARvOIvteyYXI9Z2pMNxeZkZfUVLDf37/s72-c/imageedit_1_2152645285.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-5508811765224725342</id><published>2026-10-06T11:15:13.937+03:00</published><updated>2026-10-06T11:15:13.937+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">كيف تعمل بصمة الهاتف وهل يمكن اختراقها ؟</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijUEaYjRH7ah-kKKvvfmp6XJfTn6CZNvhGn4FEwB83r0Ci0iUbrm3qeJ7xeJiYYNeCjYERsMkIu-hW9zxo07HKkPFf21298EOsf9b1o3wYgEvle7J2SwZrmY5v9pm-pHhNPuiPRtDxHxkMd7IQd8go6kF599gJa5MbAk5W01QoqLHWavAopM5zmZrYDbUY/s640/imageedit_3_6731435505.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="كيف تعمل بصمة الهاتف؟ وهل يمكن اختراقها؟" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijUEaYjRH7ah-kKKvvfmp6XJfTn6CZNvhGn4FEwB83r0Ci0iUbrm3qeJ7xeJiYYNeCjYERsMkIu-hW9zxo07HKkPFf21298EOsf9b1o3wYgEvle7J2SwZrmY5v9pm-pHhNPuiPRtDxHxkMd7IQd8go6kF599gJa5MbAk5W01QoqLHWavAopM5zmZrYDbUY/s1600/imageedit_3_6731435505.webp" title="كيف تعمل بصمة الهاتف؟ وهل يمكن اختراقها؟" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;كيف تعمل بصمة الهاتف؟ وهل يمكن اختراقها؟&lt;/h3&gt;&lt;p&gt;أصبحت &lt;b&gt;بصمة الهاتف&lt;/b&gt; واحدة من أكثر وسائل الأمان شيوعًا في &lt;b&gt;الهواتف الذكية&lt;/b&gt; الحديثة، فهي تتيح للمستخدم فتح هاتفه والوصول إلى &lt;a href="https://www.nusurtech.ca/2026/09/mobile-viruses-types-and-damages.html"&gt;التطبيقات&lt;/a&gt; والملفات بسرعة وسهولة، دون الحاجة إلى كتابة كلمة مرور في كل مرة. ومع انتشار استخدامها في الهواتف والخدمات المصرفية والتطبيقات المختلفة، يطرح الكثيرون سؤالًا مهمًا: &lt;strong&gt;كيف تعمل بصمة الهاتف؟ وهل يمكن اختراقها؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تعتمد تقنية بصمة الإصبع على تحليل خصائص فريدة موجودة في أصابع الإنسان، ثم تحويل هذه الخصائص إلى بيانات رقمية يمكن للهاتف مقارنتها عند محاولة فتح الجهاز. ورغم أن التقنية توفر مستوى مرتفعًا من الحماية، فإنها ليست نظامًا مستحيل الاختراق بنسبة 100%.&lt;/p&gt;&lt;p&gt;في هذا المقال، سنتعرف على طريقة عمل بصمة الهاتف، وأنواع مستشعرات البصمة، وكيف يتم تخزين بياناتها، وما مدى صعوبة تجاوزها، إضافة إلى أهم النصائح التي تساعدك على حماية هاتفك وبياناتك.&lt;/p&gt;&lt;h3&gt;ما هي بصمة الهاتف؟&lt;/h3&gt;&lt;p&gt;بصمة الهاتف هي نظام أمان بيومتري يعتمد على الخصائص الفريدة لبصمة إصبع المستخدم للتحقق من هويته. وتتميز بصمات الأصابع بأن تفاصيلها تختلف من شخص إلى آخر، بل إن أصابع الشخص نفسه لا تحمل بالضرورة البصمة نفسها.&lt;/p&gt;&lt;p&gt;عند تسجيل بصمة جديدة في الهاتف، يطلب الجهاز عادةً وضع الإصبع على المستشعر عدة مرات ومن زوايا مختلفة. والهدف من ذلك هو الحصول على صورة أو قراءة أكثر شمولًا لتفاصيل البصمة.&lt;/p&gt;&lt;p&gt;لكن الهاتف لا يتعامل مع البصمة بالطريقة التي قد يتخيلها البعض، فهو لا يحتفظ عادةً بصورة عادية لإصبعك لاستخدامها لاحقًا. بدلًا من ذلك، يتم استخراج مجموعة من الخصائص والأنماط وتحويلها إلى تمثيل رقمي يُستخدم في عملية التحقق.&lt;/p&gt;&lt;h3&gt;كيف تعمل بصمة الهاتف؟&lt;/h3&gt;&lt;p&gt;تبدأ العملية عندما يضع المستخدم إصبعه على مستشعر البصمة. يقوم المستشعر بالتقاط خصائص سطح الإصبع، ثم يحولها إلى بيانات يستطيع النظام تحليلها.&lt;/p&gt;&lt;p&gt;بعد ذلك، يقارن الهاتف البيانات التي تم الحصول عليها حديثًا مع البيانات المرجعية التي تم تسجيلها مسبقًا. إذا كانت درجة التطابق ضمن الحدود التي يعتمدها النظام، يسمح الهاتف بفتح الجهاز أو تنفيذ الإجراء المطلوب.&lt;/p&gt;&lt;h4&gt;المرحلة الأولى: تسجيل البصمة&lt;/h4&gt;&lt;p&gt;عند إضافة بصمة جديدة، يطلب الهاتف من المستخدم وضع إصبعه عدة مرات على المستشعر. وقد يطلب تغيير موضع الإصبع قليلًا في كل مرة حتى يتمكن النظام من تسجيل أجزاء مختلفة من البصمة.&lt;/p&gt;&lt;h4&gt;المرحلة الثانية: معالجة البيانات&lt;/h4&gt;&lt;p&gt;بعد التقاط البصمة، يقوم النظام بتحليل التفاصيل المهمة، مثل الخطوط والتفرعات والنقاط المميزة. ثم يحول هذه المعلومات إلى نموذج رقمي يمكن استخدامه في عمليات المطابقة المستقبلية.&lt;/p&gt;&lt;h4&gt;المرحلة الثالثة: التحقق من الهوية&lt;/h4&gt;&lt;p&gt;عندما تضع إصبعك مرة أخرى، يقوم المستشعر بقراءة البصمة ومقارنتها بالنموذج المسجل. إذا وجد النظام تطابقًا كافيًا، يتم قبول المحاولة.&lt;/p&gt;&lt;p&gt;هذه العملية تحدث خلال جزء صغير جدًا من الثانية، ولذلك تبدو للمستخدم فورية تقريبًا.&lt;/p&gt;&lt;h3&gt;ما أنواع مستشعرات بصمة الهاتف؟&lt;/h3&gt;&lt;p&gt;لا تعتمد جميع الهواتف على تقنية واحدة لقراءة البصمة. فقد تطورت مستشعرات البصمة بشكل كبير، وأصبحت الشركات تستخدم تقنيات مختلفة بحسب تصميم الهاتف ومستوى الأمان المطلوب.&lt;/p&gt;&lt;h4&gt;المستشعرات الضوئية&lt;/h4&gt;&lt;p&gt;تستخدم المستشعرات الضوئية الضوء لالتقاط صورة لتفاصيل البصمة. يتم بعد ذلك تحليل الصورة ومقارنتها بالبيانات المسجلة.&lt;/p&gt;&lt;p&gt;توجد هذه التقنية في بعض مستشعرات البصمة الموجودة أسفل شاشة الهاتف، وتتميز بإمكانية دمجها مع تصميم الشاشة.&lt;/p&gt;&lt;h4&gt;المستشعرات السعوية&lt;/h4&gt;&lt;p&gt;تعتمد المستشعرات السعوية على قياس الاختلافات الكهربائية الدقيقة الناتجة عن ملامسة الإصبع للمستشعر. وتقوم بإنشاء خريطة للتفاصيل الموجودة في البصمة.&lt;/p&gt;&lt;p&gt;كانت هذه التقنية شائعة جدًا في الهواتف التي تحتوي على زر بصمة فعلي، وما زالت مستخدمة في بعض الأجهزة.&lt;/p&gt;&lt;h4&gt;المستشعرات فوق الصوتية&lt;/h4&gt;&lt;p&gt;تستخدم بعض الهواتف الحديثة مستشعرات فوق صوتية لإرسال موجات صوتية وقياس كيفية انعكاسها عن سطح الإصبع.&lt;/p&gt;&lt;p&gt;تسمح هذه التقنية بقراءة تفاصيل البصمة بطريقة مختلفة عن المستشعرات الضوئية، وقد تساعد في تحسين الدقة والقدرة على العمل في ظروف معينة.&lt;/p&gt;&lt;h3&gt;أين يتم تخزين بصمة الإصبع؟&lt;/h3&gt;&lt;p&gt;من أكثر الأسئلة التي تثير القلق لدى المستخدمين: هل يتم إرسال بصمة الإصبع إلى الشركة المصنعة أو تخزينها على الإنترنت؟&lt;/p&gt;&lt;p&gt;في الأنظمة الحديثة، يتم تصميم بيانات المصادقة البيومترية بحيث تكون محمية داخل الهاتف، وغالبًا ما تُستخدم بيئات أو وحدات أمان مخصصة لعزل هذه البيانات عن بقية النظام.&lt;/p&gt;&lt;p&gt;والفكرة الأساسية هي أن التطبيقات العادية لا ينبغي أن تحصل على بيانات البصمة الخام. فعندما تستخدم بصمتك لفتح تطبيق مصرفي مثلًا، يحصل التطبيق عادةً على نتيجة المصادقة، أي أن النظام أخبره بأن المستخدم تم التحقق منه، بدلًا من إعطائه نسخة من بصمة الإصبع نفسها.&lt;/p&gt;&lt;p&gt;وهذا التصميم يقلل من مخاطر سرقة بيانات البصمة واستخدامها خارج الهاتف.&lt;/p&gt;&lt;h3&gt;هل يمكن اختراق بصمة الهاتف؟&lt;/h3&gt;&lt;p&gt;الإجابة المختصرة هي: &lt;strong&gt;نعم، من الناحية النظرية يمكن تجاوز أنظمة البصمة في بعض الظروف، لكنها ليست عملية سهلة في الأجهزة الحديثة المصممة بشكل جيد.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لا توجد وسيلة حماية تقنية مثالية، وبصمة الإصبع ليست استثناءً. تعتمد درجة الأمان على جودة المستشعر، وطريقة معالجة البيانات، والبرمجيات المستخدمة، بالإضافة إلى وجود وسائل حماية أخرى مثل رمز المرور.&lt;/p&gt;&lt;h4&gt;هل يمكن استخدام صورة للإصبع؟&lt;/h4&gt;&lt;p&gt;في معظم الهواتف الحديثة، لا تكفي صورة عادية للإصبع لتجاوز نظام البصمة. فالمستشعر لا يعتمد بالضرورة على الشكل المرئي للبصمة فقط، بل قد يستخدم خصائص أخرى للتحقق من أن ما يلامس المستشعر هو إصبع حقيقي.&lt;/p&gt;&lt;p&gt;ومع ذلك، تختلف درجة مقاومة محاولات الخداع من جهاز إلى آخر، ولهذا لا يمكن اعتبار جميع الهواتف متساوية في مستوى الأمان.&lt;/p&gt;&lt;h4&gt;ماذا عن البصمة المزيفة؟&lt;/h4&gt;&lt;p&gt;يمكن من الناحية التقنية تصنيع نماذج تحاكي بعض خصائص بصمة الإصبع، وقد أظهرت أبحاث أمنية سابقة إمكانية خداع بعض المستشعرات في ظروف معينة.&lt;/p&gt;&lt;p&gt;لكن تحويل ذلك إلى هجوم عملي ضد هاتف حديث قد يتطلب معرفة مسبقة ببصمة الضحية ووسائل متخصصة ووقتًا وجهدًا، كما أن بعض الأنظمة تستخدم تقنيات تساعد على اكتشاف محاولات الخداع.&lt;/p&gt;&lt;p&gt;لذلك، فإن احتمال تعرض المستخدم العادي لهذا النوع من الهجمات يختلف كثيرًا عن السيناريوهات التي تستهدف أشخاصًا أو أجهزة ذات قيمة عالية.&lt;/p&gt;&lt;h3&gt;هل بصمة الإصبع أكثر أمانًا من كلمة المرور؟&lt;/h3&gt;&lt;p&gt;ليس من الصحيح القول إن البصمة دائمًا أكثر أمانًا من كلمة المرور أو العكس. لكل وسيلة مزايا وقيود مختلفة.&lt;/p&gt;&lt;p&gt;تتميز البصمة بسهولة الاستخدام، فلا تحتاج إلى تذكر كلمة مرور طويلة، كما يصعب على شخص آخر معرفة بصمتك بمجرد النظر إليك.&lt;/p&gt;&lt;p&gt;في المقابل، كلمة المرور أو رمز المرور الجيد يمكن تغييره إذا تم كشفه، بينما لا يمكنك تغيير بصمة إصبعك بالطريقة نفسها التي تغير بها كلمة المرور.&lt;/p&gt;&lt;p&gt;ولهذا تعتمد الهواتف الحديثة عادةً على الجمع بين الطريقتين. يمكن استخدام البصمة للراحة والسرعة، بينما يبقى رمز المرور وسيلة أساسية للحماية.&lt;/p&gt;&lt;h3&gt;متى يطلب الهاتف رمز المرور بدلًا من البصمة؟&lt;/h3&gt;&lt;p&gt;قد تلاحظ أحيانًا أن هاتفك يطلب رمز المرور رغم أنك تستخدم بصمة الإصبع عادةً. وهذا ليس بالضرورة دليلًا على وجود مشكلة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;&lt;b&gt;بعد إعادة تشغيل الهاتف&lt;/b&gt;&amp;nbsp;: تطلب أنظمة الهواتف عادةً رمز المرور أو كلمة المرور بعد إعادة تشغيل الجهاز، قبل السماح باستخدام المصادقة البيومترية بشكل طبيعي.&lt;/li&gt;&lt;li&gt;&lt;b&gt;بعد فترة من عدم الاستخدام&lt;/b&gt;&amp;nbsp;: قد يطلب الهاتف رمز المرور بعد مرور فترة معينة دون فتح الجهاز، كإجراء أمني إضافي.&lt;/li&gt;&lt;li&gt;&lt;b&gt;بعد فشل محاولات البصمة&lt;/b&gt;&amp;nbsp;: إذا حدثت عدة محاولات فاشلة لقراءة البصمة، قد يتم تعطيل فتح الهاتف بالبصمة مؤقتًا وإجبار المستخدم على إدخال رمز المرور.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;هذه الإجراءات مهمة لأنها تمنع الاعتماد الكامل على البصمة وتوفر طبقة أمان إضافية.&lt;/p&gt;&lt;h3&gt;ما نقاط ضعف بصمة الهاتف؟&lt;/h3&gt;&lt;p&gt;رغم قوتها، توجد بعض القيود التي يجب معرفتها. أولًا، بصمة الإصبع مرتبطة بجزء من جسم الإنسان ولا يمكن تغييرها بسهولة إذا أصبحت بياناتها مكشوفة.&lt;/p&gt;&lt;p&gt;كما أن جودة المستشعر تؤثر في دقة النظام. وقد تواجه صعوبة في التعرف على الإصبع إذا كان مبللًا أو متسخًا أو إذا كانت هناك عوامل تؤثر في قراءة البصمة.&lt;/p&gt;&lt;p&gt;كذلك، يمكن أن تختلف الحماية بين هاتف وآخر؛ فالمستشعرات والبرمجيات المستخدمة في هاتف اقتصادي قد لا توفر المستوى نفسه الموجود في هاتف رائد حديث.&lt;/p&gt;&lt;h3&gt;كيف تجعل بصمة هاتفك أكثر أمانًا؟&lt;/h3&gt;&lt;p&gt;أفضل طريقة للاستفادة من بصمة الهاتف هي استخدامها كجزء من منظومة أمان متكاملة، وليس باعتبارها وسيلة الحماية الوحيدة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;استخدم رمز مرور قويًا&lt;/b&gt;&amp;nbsp;: اختر رمز مرور يصعب تخمينه، وتجنب الأرقام البسيطة أو المعلومات الشخصية المعروفة، مثل تاريخ الميلاد.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;لا تسجل بصمتك على أجهزة غير موثوقة&lt;/b&gt;&amp;nbsp;: إذا كان الهاتف يستخدمه أشخاص آخرون أو لم تكن متأكدًا من مستوى حمايته، فمن الأفضل عدم إضافة بصمتك إليه.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;حدّث نظام الهاتف&lt;/b&gt;&amp;nbsp;: تتضمن تحديثات أنظمة التشغيل أحيانًا إصلاحات لمشكلات أمنية، ولذلك من المهم تثبيت التحديثات الرسمية عندما تكون متاحة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;فعّل ميزات الحماية الإضافية&lt;/b&gt;&amp;nbsp;: إذا كان هاتفك يوفر خيارات مثل قفل الجهاز عن بُعد أو تحديد موقعه أو حماية التطبيقات الحساسة، فمن الأفضل تفعيل الميزات المناسبة لاحتياجاتك.&lt;/p&gt;&lt;h3&gt;هل يجب الاعتماد على بصمة الهاتف؟&lt;/h3&gt;&lt;p&gt;نعم، يمكن الاعتماد على بصمة الهاتف كوسيلة عملية وسريعة للحماية، خصوصًا عندما تكون مستخدمة على جهاز حديث مع رمز مرور قوي.&lt;/p&gt;&lt;p&gt;لكن من الأفضل النظر إليها باعتبارها &lt;strong&gt;جزءًا من نظام أمان متعدد الطبقات&lt;/strong&gt;. فالأمان الحقيقي لا يعتمد على المستشعر وحده، وإنما على طريقة تصميم الهاتف وتخزين بيانات المصادقة، وقوة رمز المرور، وتحديثات النظام، وسلوك المستخدم.&lt;/p&gt;&lt;p&gt;تعمل بصمة الهاتف من خلال قراءة خصائص مميزة لبصمة الإصبع وتحويلها إلى بيانات رقمية يتم استخدامها للتحقق من هوية المستخدم. وتختلف طريقة القراءة بحسب نوع المستشعر، سواء كان ضوئيًا أو سعويًا أو فوق صوتي.&lt;/p&gt;&lt;p&gt;أما عن إمكانية اختراق البصمة، فالإجابة ليست نعم أو لا بشكل مطلق. فقد تمكن الباحثون في بعض الحالات من تجاوز أنواع معينة من أنظمة البصمة، لكن أنظمة الهواتف الحديثة تتضمن طبقات متعددة تهدف إلى تقليل هذه المخاطر.&lt;/p&gt;&lt;p&gt;ولهذا، فإن أفضل حماية لهاتفك هي الجمع بين &lt;strong&gt;بصمة الإصبع ورمز مرور قوي وتحديثات النظام وميزات الحماية الإضافية&lt;/strong&gt;. وبذلك تحصل على توازن جيد بين سهولة الاستخدام ومستوى الأمان.&lt;/p&gt;&lt;p&gt;إذا أردت، أستطيع أيضًا تجهيز &lt;strong&gt;نسخة SEO أقوى للمقال&lt;/strong&gt; تشمل وصف الميتا، الكلمة المفتاحية الرئيسية، الكلمات المفتاحية الفرعية، وFAQ مناسب لنتائج Google.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/5508811765224725342/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/how-smartphone-fingerprint-works-can-it-be-hacked.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5508811765224725342" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/5508811765224725342" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/how-smartphone-fingerprint-works-can-it-be-hacked.html" rel="alternate" title="كيف تعمل بصمة الهاتف وهل يمكن اختراقها ؟" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEijUEaYjRH7ah-kKKvvfmp6XJfTn6CZNvhGn4FEwB83r0Ci0iUbrm3qeJ7xeJiYYNeCjYERsMkIu-hW9zxo07HKkPFf21298EOsf9b1o3wYgEvle7J2SwZrmY5v9pm-pHhNPuiPRtDxHxkMd7IQd8go6kF599gJa5MbAk5W01QoqLHWavAopM5zmZrYDbUY/s72-c/imageedit_3_6731435505.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-951180186684621373</id><published>2026-10-05T14:09:38.567+03:00</published><updated>2026-10-05T14:09:39.137+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">أفضل 12 ميزة ذكية في Google Drive ربما لم تكن تعرفها</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix4hk8YxO86XB17MVMYLBdSlL7Oj5WEef80hOD9eKNcdO6dDQ5BTjogX5fzvxSNMt-Jm2PThwkvUOVQyFcPqb0Fvb17073zgcCMMj1Xqqyb5UR4CnHQelZl8HNq18wdgq6CRxRN_FgfD7SFQDTqt1lwYBLSa4h8zOZFHZE1AdOIXvFWaaqY7Zd22FksJeu/s640/imageedit_1_4762295993.webp" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="أفضل 12 ميزة ذكية في Google Drive ربما لم تكن تعرفها" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix4hk8YxO86XB17MVMYLBdSlL7Oj5WEef80hOD9eKNcdO6dDQ5BTjogX5fzvxSNMt-Jm2PThwkvUOVQyFcPqb0Fvb17073zgcCMMj1Xqqyb5UR4CnHQelZl8HNq18wdgq6CRxRN_FgfD7SFQDTqt1lwYBLSa4h8zOZFHZE1AdOIXvFWaaqY7Zd22FksJeu/s1600/imageedit_1_4762295993.webp" title="أفضل 12 ميزة ذكية في Google Drive ربما لم تكن تعرفها" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Google Drive ليس مجرد مساحة لتخزين الملفات: 12 ميزة ذكية ربما لم تكن تعرفها&lt;/h3&gt;
&lt;p&gt;عندما نسمع اسم &lt;strong&gt;Google Drive&lt;/strong&gt;، غالبًا ما نفكر في مكان نرفع إليه الصور والملفات ثم نعود إليها عند الحاجة. لكن التطبيق يقدم مجموعة أكبر بكثير من الأدوات التي يمكن أن تساعدك في &lt;strong&gt;تنظيم ملفاتك، البحث عنها، مشاركة المستندات، مسح الأوراق ضوئيًا، واستعادة الملفات المحذوفة&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;ومع استمرار جوجل في تطوير واجهة Drive وتحسين تجربة البحث وإدارة الملفات، أصبح من المفيد معرفة الأدوات الموجودة داخل الخدمة وكيفية الاستفادة منها بالشكل الصحيح.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;1. استعادة الملفات التي حذفتها بالخطأ&lt;/h3&gt;
&lt;p&gt;حذف ملف مهم بالخطأ لا يعني بالضرورة أنك فقدته نهائيًا.&lt;/p&gt;
&lt;p&gt;يحتفظ Google Drive بالملفات المحذوفة في &lt;strong&gt;سلة المهملات&lt;/strong&gt; لفترة محددة قبل حذفها نهائيًا.&lt;/p&gt;
&lt;p&gt;للاستعادة:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;افتح Google Drive.&lt;/li&gt;
&lt;li&gt;انتقل إلى &lt;strong&gt;Trash – سلة المهملات&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;ابحث عن الملف.&lt;/li&gt;
&lt;li&gt;اضغط على الخيارات بجوار الملف.&lt;/li&gt;
&lt;li&gt;اختر &lt;strong&gt;Restore – استعادة&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;سيعود الملف إلى موقعه السابق داخل Drive، ما دام لم يتم حذفه نهائيًا.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;2. تحويل الهاتف إلى ماسح ضوئي للمستندات&lt;/h3&gt;
&lt;p&gt;لا تحتاج دائمًا إلى تثبيت تطبيق منفصل لمسح الأوراق والمستندات.&lt;/p&gt;
&lt;p&gt;في الأجهزة التي يدعم فيها تطبيق Drive ميزة المسح الضوئي، يمكنك استخدام الكاميرا لالتقاط المستند وتحويله إلى ملف رقمي، ثم حفظه داخل حسابك.&lt;/p&gt;
&lt;p&gt;وهذا مفيد جدًا عند الاحتفاظ بـ:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;الإيصالات.&lt;/li&gt;
&lt;li&gt;المستندات الدراسية.&lt;/li&gt;
&lt;li&gt;الفواتير.&lt;/li&gt;
&lt;li&gt;الأوراق الرسمية.&lt;/li&gt;
&lt;li&gt;الملاحظات المكتوبة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;وبذلك يصبح Drive أشبه بماسح ضوئي صغير داخل هاتفك.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;3. البحث عن المعلومات الموجودة داخل الصور والمستندات&lt;/h3&gt;
&lt;p&gt;من أقوى الأشياء في منظومة Google قدرتها على تحليل محتوى الملفات.&lt;/p&gt;
&lt;p&gt;إذا كانت لديك مستندات أو صور تحتوي على نصوص، فقد تتمكن من العثور عليها باستخدام البحث في Drive، خصوصًا عندما يكون المحتوى قابلاً للتعرّف عليه.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، إذا احتفظت بصورة لفاتورة أو مستند يحتوي على كلمة معينة، يمكنك تجربة البحث عن الكلمة داخل Drive بدلًا من فتح عشرات الصور واحدة تلو الأخرى.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ملاحظة:&lt;/strong&gt; دقة التعرف على النص تختلف حسب جودة الصورة، واللغة، ونوع المستند.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 style="text-align: right;"&gt;4. مشاركة الملفات دون إرسالها مباشرة&lt;/h3&gt;
&lt;p&gt;هل حاولت إرسال ملف كبير عبر تطبيقات المحادثة وواجهت مشكلة في الحجم؟&lt;/p&gt;
&lt;p&gt;بدلًا من إرسال الملف نفسه، يمكنك رفعه إلى Google Drive ثم مشاركة الرابط.&lt;/p&gt;
&lt;p&gt;الطريقة:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;حدد الملف.&lt;/li&gt;
&lt;li&gt;اضغط &lt;strong&gt;Share – مشاركة&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;حدد الأشخاص الذين تريد منحهم الوصول، أو اضبط إعدادات الرابط.&lt;/li&gt;
&lt;li&gt;اختر &lt;strong&gt;Copy link – نسخ الرابط&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;أرسل الرابط للشخص المطلوب.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;والأهم هو مراجعة &lt;strong&gt;صلاحيات الوصول&lt;/strong&gt; قبل مشاركة الرابط، لأن الرابط وحده لا يعني بالضرورة أن الملف متاح للجميع.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;5. التحكم في من يستطيع مشاهدة ملفاتك أو تعديلها&lt;/h3&gt;
&lt;p&gt;من أهم مميزات Google Drive أنه لا يقتصر على مشاركة الملف فقط، بل يسمح لك بتحديد مستوى الوصول.&lt;/p&gt;
&lt;p&gt;يمكنك، بحسب نوع المشاركة، منح الشخص صلاحية:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Viewer:&lt;/strong&gt; مشاهدة الملف فقط.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Commenter:&lt;/strong&gt; مشاهدة الملف وإضافة التعليقات في الملفات المدعومة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Editor:&lt;/strong&gt; تعديل الملف.&lt;/p&gt;
&lt;p&gt;وهذا مهم جدًا عند العمل على ملفات مشتركة مع زملاء الدراسة أو فريق العمل.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;6. فتح بعض الملفات دون اتصال بالإنترنت&lt;/h3&gt;
&lt;p&gt;ماذا لو كنت مسافرًا أو في مكان لا توجد فيه شبكة إنترنت؟&lt;/p&gt;
&lt;p&gt;يمكن لبعض ملفات Google Drive وملفات Google Workspace أن تكون متاحة للعمل دون اتصال بعد تفعيل الخيار المناسب.&lt;/p&gt;
&lt;p&gt;عادةً ستجد خيار &lt;strong&gt;Available offline – متاح بلا اتصال&lt;/strong&gt; ضمن قائمة الملف.&lt;/p&gt;
&lt;p&gt;بعد ذلك يمكنك الوصول إلى الملف عندما لا يتوفر الإنترنت، مع ملاحظة أن إمكانيات العمل دون اتصال تختلف حسب نوع الملف والجهاز والإعدادات.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;7. معرفة الملفات التي تستهلك مساحة التخزين&lt;/h3&gt;
&lt;p&gt;مساحة حساب Google ليست بلا حدود، وتُستخدم مساحة التخزين المشتركة لخدمات مثل &lt;strong&gt;Google Drive وGmail وGoogle Photos&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;لذلك، عندما تبدأ المساحة في الامتلاء، من المفيد معرفة الملفات الكبيرة أولًا.&lt;/p&gt;
&lt;p&gt;من قسم &lt;strong&gt;Storage – مساحة التخزين&lt;/strong&gt; يمكنك مراجعة الملفات التي تشغل مساحة أكبر، ثم حذف الملفات التي لم تعد تحتاج إليها.&lt;/p&gt;
&lt;p&gt;وهذه الطريقة أفضل من حذف الملفات عشوائيًا.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;8. استخدام البحث بطريقة أكثر ذكاءً&lt;/h3&gt;
&lt;p&gt;واحدة من أكثر الأدوات التي يتم تجاهلها في Drive هي أدوات البحث.&lt;/p&gt;
&lt;p&gt;بدلًا من كتابة اسم الملف فقط، يمكنك تضييق نتائج البحث باستخدام معايير مختلفة، مثل:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;نوع الملف.&lt;/li&gt;
&lt;li&gt;الشخص الذي يملك الملف.&lt;/li&gt;
&lt;li&gt;تاريخ التعديل.&lt;/li&gt;
&lt;li&gt;مكان وجود الملف.&lt;/li&gt;
&lt;li&gt;الكلمات الموجودة في اسم الملف أو محتواه.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;كلما كان حسابك يحتوي على مئات أو آلاف الملفات، أصبحت فلاتر البحث أكثر أهمية.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;9. النسخ الاحتياطي للبيانات: انتبه إلى ما ينسخه Google فعليًا&lt;/h3&gt;
&lt;p&gt;يعتقد بعض المستخدمين أن تفعيل Google Drive يعني تلقائيًا نسخ كل شيء موجود على الهاتف.&lt;/p&gt;
&lt;p&gt;لكن الأمر أكثر تعقيدًا من ذلك.&lt;/p&gt;
&lt;p&gt;في أجهزة Android، يمكن لخدمة النسخ الاحتياطي من Google حفظ أنواع مختلفة من بيانات الجهاز، لكن &lt;strong&gt;ما يتم نسخه تحديدًا يعتمد على الهاتف وإصدار Android والإعدادات&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;لذلك لا تفترض أن كل صورة أو كل ملف على هاتفك محفوظ تلقائيًا.&lt;/p&gt;
&lt;p&gt;إذا كانت الصور مهمة، تأكد أيضًا من إعدادات &lt;strong&gt;Google Photos&lt;/strong&gt;، وليس Drive فقط.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;10. العثور على الهاتف عند فقدانه&lt;/h3&gt;
&lt;p&gt;إذا فقدت هاتف Android، توفر Google خدمة &lt;strong&gt;Find My Device&lt;/strong&gt; لمساعدتك في التعامل مع الجهاز عن بُعد، وفق حالة الجهاز وإعداداته.&lt;/p&gt;
&lt;p&gt;يمكن للخدمة، عندما تتوفر الشروط المطلوبة، أن تساعدك في:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;تحديد موقع الجهاز.&lt;/li&gt;
&lt;li&gt;تشغيل صوت للمساعدة في العثور عليه.&lt;/li&gt;
&lt;li&gt;قفل الجهاز.&lt;/li&gt;
&lt;li&gt;عرض رسالة أو معلومات للتواصل.&lt;/li&gt;
&lt;li&gt;مسح بيانات الجهاز عن بُعد في الحالات المناسبة.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;وهذه من الأدوات التي يُفضّل إعدادها &lt;strong&gt;قبل&lt;/strong&gt; فقدان الهاتف، وليس بعده.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;11. استخراج النص من الصور والمستندات&lt;/h3&gt;
&lt;p&gt;لديك صورة تحتوي على صفحة كاملة من الكتاب أو مستند ورقي وتريد استخراج النص؟&lt;/p&gt;
&lt;p&gt;يمكن استخدام أدوات Google لاستخراج النص من بعض الصور والمستندات، ومن الطرق المعروفة فتح الصورة باستخدام &lt;strong&gt;Google Docs&lt;/strong&gt; عندما يكون الخيار متاحًا.&lt;/p&gt;
&lt;p&gt;قد يتم تحويل الصورة إلى مستند يحتوي على النص المستخرج.&lt;/p&gt;
&lt;p&gt;لكن النتيجة ليست دائمًا مثالية؛ فالصور غير الواضحة، والخطوط المعقدة، واللغات المختلفة قد تؤثر في دقة التعرف على النص.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;12. استعادة الإصدارات السابقة من الملفات&lt;/h3&gt;
&lt;p&gt;هذه الميزة مهمة خصوصًا عند العمل على مستندات أو ملفات يتم تعديلها باستمرار.&lt;/p&gt;
&lt;p&gt;في خدمات Google Workspace مثل Google Docs وSheets وSlides، يمكنك استخدام &lt;strong&gt;Version history – سجل الإصدارات&lt;/strong&gt; لمراجعة التعديلات السابقة والعودة إلى إصدار سابق عند الحاجة.&lt;/p&gt;
&lt;p&gt;وهذا يمنحك طبقة إضافية من الأمان عند تعديل مستند مهم، بدلًا من القلق من أن يؤدي خطأ واحد إلى فقدان العمل السابق.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ماذا تغير في Google Drive؟&lt;/h3&gt;
&lt;p&gt;تعمل Google باستمرار على تطوير تصميم وتطبيقات منظومتها، لذلك قد تلاحظ اختلافات في الواجهة بين جهاز وآخر أو بين إصدار وآخر.&lt;/p&gt;
&lt;p&gt;وقد تشمل التغييرات:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;تصميمًا أكثر حداثة.&lt;/li&gt;
&lt;li&gt;تحسينات في عرض الملفات.&lt;/li&gt;
&lt;li&gt;أدوات بحث وتنظيم أفضل.&lt;/li&gt;
&lt;li&gt;تحسينات في المشاركة.&lt;/li&gt;
&lt;li&gt;تكاملًا أكبر مع خدمات Google الأخرى.&lt;/li&gt;
&lt;li&gt;تحسينات في الأداء وتجربة الاستخدام.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;لكن من المهم معرفة أن &lt;strong&gt;ظهور ميزة معينة قد يختلف حسب الجهاز، ونظام التشغيل، وإصدار التطبيق، والحساب، والمنطقة&lt;/strong&gt;؛ لذلك لا يعني عدم ظهور خيار معين أن هاتفك به مشكلة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;كيف تستفيد من Google Drive بأمان؟&lt;/h3&gt;
&lt;p&gt;قبل رفع ملفاتك الحساسة إلى أي خدمة سحابية، انتبه إلى إعدادات المشاركة.&lt;/p&gt;
&lt;p&gt;لا تجعل الملف متاحًا لأي شخص لديه الرابط إلا عندما يكون ذلك مقصودًا فعلًا.&lt;/p&gt;
&lt;p&gt;ومن الأفضل أيضًا:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;استخدام كلمة مرور قوية لحساب Google.&lt;/li&gt;
&lt;li&gt;تفعيل التحقق بخطوتين.&lt;/li&gt;
&lt;li&gt;مراجعة الملفات التي تمت مشاركتها مع الآخرين.&lt;/li&gt;
&lt;li&gt;حذف الملفات القديمة التي لم تعد تحتاج إليها.&lt;/li&gt;
&lt;li&gt;مراجعة مساحة التخزين بشكل دوري.&lt;/li&gt;
&lt;li&gt;الاحتفاظ بنسخة إضافية من الملفات شديدة الأهمية.&lt;/li&gt;&lt;/ul&gt;</content><link href="https://www.nusurtech.ca/feeds/951180186684621373/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/top-12-smart-google-drive-features-you-didnt-know.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/951180186684621373" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/951180186684621373" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/top-12-smart-google-drive-features-you-didnt-know.html" rel="alternate" title="أفضل 12 ميزة ذكية في Google Drive ربما لم تكن تعرفها" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEix4hk8YxO86XB17MVMYLBdSlL7Oj5WEef80hOD9eKNcdO6dDQ5BTjogX5fzvxSNMt-Jm2PThwkvUOVQyFcPqb0Fvb17073zgcCMMj1Xqqyb5UR4CnHQelZl8HNq18wdgq6CRxRN_FgfD7SFQDTqt1lwYBLSa4h8zOZFHZE1AdOIXvFWaaqY7Zd22FksJeu/s72-c/imageedit_1_4762295993.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-995073623078851816</id><published>2026-10-05T10:13:22.306+03:00</published><updated>2026-10-05T10:20:12.735+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="مقالات"/><title type="text">ما هو السيرفر؟ شرح شامل للسيرفر ومكوناته وكيف يعمل</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAJGW9VNwFWPJzGqQ1-KTSQsIAXwqBthTTr8nq6FH8JlMzeZg4D2oYuinO8HIQC_SaCBvQ4VlUmw-yoUNM3AOnBP7LSmydATw4Hh2Mv_IO7spL1z9Net5E8uHAR4iywR9jLUBK90jxpp_J3iuWfVwdvm2wdIOJwFMN210kyPDbGJtOOi6nMQQCyEMz8ieX/s640/imageedit_1_6113856441.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="ما هو السيرفر؟ شرح شامل للسيرفر ومكوناته وكيف يعمل" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAJGW9VNwFWPJzGqQ1-KTSQsIAXwqBthTTr8nq6FH8JlMzeZg4D2oYuinO8HIQC_SaCBvQ4VlUmw-yoUNM3AOnBP7LSmydATw4Hh2Mv_IO7spL1z9Net5E8uHAR4iywR9jLUBK90jxpp_J3iuWfVwdvm2wdIOJwFMN210kyPDbGJtOOi6nMQQCyEMz8ieX/s1600/imageedit_1_6113856441.webp" title="ما هو السيرفر؟ شرح شامل للسيرفر ومكوناته وكيف يعمل" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو السيرفر؟ شرح شامل للسيرفر ومكوناته وكيف يعمل&lt;/h3&gt;
&lt;p&gt;عند تصفح أي موقع إلكتروني، أو تحميل ملف من الإنترنت، أو استخدام نظام إلكتروني تابع لشركة أو جامعة، هناك جهاز أو مجموعة من الأجهزة تعمل في الخلفية لتقديم هذه الخدمة. هذه الأجهزة تُعرف باسم &lt;strong&gt;السيرفر &lt;a href="https://www.nusurtech.ca/2022/12/install-mamp-server-on-windows.html" target="_blank"&gt;Server&lt;/a&gt;&lt;/strong&gt; أو &lt;strong&gt;الخادم&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;لكن ما هو &lt;a href="https://www.nusurtech.ca/2026/05/wamp-server.html" target="_blank"&gt;السيرفر&lt;/a&gt; تحديدًا؟ وما مكوناته؟ وكيف يستطيع التعامل مع آلاف الطلبات في الوقت نفسه؟ في هذا المقال سنتعرف على مفهوم السيرفر، وأهم مكوناته، وأنواع السيرفرات، وطريقة عملها، والفرق بينها وبين أجهزة الكمبيوتر العادية.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما هو السيرفر Server؟&lt;/h3&gt;
&lt;p&gt;السيرفر هو جهاز حاسوب أو نظام حاسوبي مصمم لتقديم خدمات أو موارد لأجهزة ومستخدمين آخرين عبر شبكة محلية أو الإنترنت.&lt;/p&gt;
&lt;p&gt;فعندما تفتح موقعًا إلكترونيًا، يرسل جهازك طلبًا إلى السيرفر الذي يستضيف الموقع. يقوم السيرفر باستقبال الطلب ومعالجته، ثم يرسل البيانات المطلوبة إلى جهازك ليتم عرض الصفحة.&lt;/p&gt;
&lt;p&gt;بشكل مبسط:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;المستخدم → الإنترنت → السيرفر → معالجة الطلب → إرسال البيانات → المستخدم&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;ولا يشترط أن يكون السيرفر جهازًا واحدًا فقط؛ فقد تعتمد الخدمات الكبيرة على مجموعة من السيرفرات التي تعمل معًا لتوزيع الأحمال وتحسين الأداء والاعتمادية.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما الفرق بين السيرفر والكمبيوتر العادي؟&lt;/h3&gt;
&lt;p&gt;من الناحية الأساسية، السيرفر والكمبيوتر الشخصي يشتركان في مكونات رئيسية مثل المعالج والذاكرة والتخزين، لكن السيرفرات تُصمم عادةً للعمل لفترات طويلة وتحمل أعداد كبيرة من العمليات والطلبات.&lt;/p&gt;
&lt;p&gt;ومن أهم الاختلافات:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;السيرفرات مصممة للتعامل مع عدد كبير من المستخدمين والطلبات.&lt;/li&gt;
&lt;li&gt;يمكن أن تحتوي على معالجات وذاكرة ذات قدرات عالية.&lt;/li&gt;
&lt;li&gt;تتوفر فيها تقنيات لزيادة الاعتمادية، مثل مزودات الطاقة المتعددة وذاكرة ECC في بعض الأنظمة.&lt;/li&gt;
&lt;li&gt;يمكن إدارتها ومراقبتها عن بُعد.&lt;/li&gt;
&lt;li&gt;غالبًا ما تستخدم أنظمة تخزين متعددة وتقنيات مثل RAID.&lt;/li&gt;
&lt;li&gt;يتم تصميم بيئة تشغيلها مع مراعاة التبريد والاستمرارية.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 style="text-align: right;"&gt;أهم مكونات السيرفر&lt;/h3&gt;
&lt;p&gt;يتكون السيرفر من مجموعة من المكونات المادية والبرمجية التي تعمل معًا لتقديم الخدمة المطلوبة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;1. المعالج CPU&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;المعالج هو أحد أهم أجزاء السيرفر، فهو المسؤول عن تنفيذ التعليمات ومعالجة العمليات التي تطلبها البرامج.&lt;/p&gt;
&lt;p&gt;كلما زادت طبيعة الأحمال التي يعمل عليها السيرفر، زادت أهمية اختيار معالج مناسب من حيث عدد الأنوية، الأداء، واستهلاك الطاقة.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، سيرفر قاعدة بيانات كبيرة قد يحتاج إلى موارد معالجة أكبر من سيرفر يستخدم لتخزين ملفات بسيطة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;2. ذاكرة الوصول العشوائي RAM&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تستخدم RAM لتخزين البيانات والبرامج التي يحتاج إليها السيرفر أثناء التشغيل.&lt;/p&gt;
&lt;p&gt;وجود ذاكرة RAM كافية يساعد النظام على التعامل مع عدد أكبر من العمليات في الوقت نفسه، خصوصًا عند تشغيل قواعد البيانات والتطبيقات التي تتطلب كمية كبيرة من الذاكرة.&lt;/p&gt;
&lt;p&gt;وتستخدم بعض السيرفرات ذاكرة &lt;strong&gt;ECC RAM&lt;/strong&gt;، وهي تقنية تساعد في اكتشاف وتصحيح بعض أخطاء الذاكرة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;3. وحدات التخزين Storage&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يحتاج السيرفر إلى وحدات تخزين لحفظ نظام التشغيل والبرامج والملفات وقواعد البيانات.&lt;/p&gt;
&lt;p&gt;ومن أشهر أنواع التخزين:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HDD:&lt;/strong&gt; يعتمد على الأقراص المغناطيسية ويوفر سعات كبيرة بتكلفة أقل عادةً.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SSD:&lt;/strong&gt; يعتمد على الذاكرة الفلاشية ويوفر سرعة أعلى من الأقراص التقليدية.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NVMe SSD:&lt;/strong&gt; يستخدم واجهة PCIe ويوفر أداءً عاليًا في عمليات القراءة والكتابة.&lt;/p&gt;
&lt;p&gt;اختيار نوع التخزين يعتمد على طبيعة السيرفر والسرعة والسعة المطلوبة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;4. اللوحة الأم Motherboard&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;اللوحة الأم هي المكوّن الذي يربط معظم أجزاء السيرفر ببعضها، بما في ذلك المعالج والذاكرة ووحدات التخزين وبطاقات الشبكة ومكونات التوسعة.&lt;/p&gt;
&lt;p&gt;ويختلف تصميم اللوحات الأم الخاصة بالسيرفرات عن كثير من اللوحات المستخدمة في أجهزة الكمبيوتر الشخصية من حيث دعم المعالجات والذاكرة ومكونات التوسعة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;5. كرت الشبكة Network Interface Card&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يعرف اختصارًا باسم &lt;strong&gt;NIC&lt;/strong&gt;، وهو المسؤول عن اتصال السيرفر بالشبكة.&lt;/p&gt;
&lt;p&gt;ومن خلاله يستطيع السيرفر استقبال طلبات المستخدمين وإرسال البيانات إليهم.&lt;/p&gt;
&lt;p&gt;في مراكز البيانات يمكن أن تحتوي السيرفرات على أكثر من منفذ شبكة لتوفير سرعات أعلى أو مسارات اتصال إضافية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;6. مزود الطاقة Power Supply&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يحتاج السيرفر إلى مصدر طاقة مستقر لتشغيل مكوناته.&lt;/p&gt;
&lt;p&gt;وفي السيرفرات التي تتطلب مستوى عالٍ من الاعتمادية، يمكن استخدام أكثر من مزود طاقة بحيث يستمر النظام في العمل في حال تعطل أحدها، بحسب تصميم الجهاز والبنية الكهربائية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;7. نظام التبريد&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;تنتج مكونات السيرفر، خصوصًا المعالجات ووحدات التخزين ومكونات الطاقة، حرارة أثناء التشغيل.&lt;/p&gt;
&lt;p&gt;لذلك تحتوي السيرفرات على أنظمة تبريد تشمل المراوح والمشتتات الحرارية وتصميمًا مناسبًا لتدفق الهواء.&lt;/p&gt;
&lt;p&gt;وفي مراكز البيانات، لا يعتمد الأمر على مراوح السيرفر فقط، بل توجد أنظمة تبريد وتهوية خاصة بالبيئة التي توجد فيها الأجهزة.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;&lt;b&gt;8. RAID Controller&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;يمكن استخدام تقنية RAID لإدارة مجموعة من وحدات التخزين بطريقة توفر مستويات مختلفة من الأداء أو تحمل تعطل أحد الأقراص، بحسب مستوى RAID المستخدم.&lt;/p&gt;
&lt;p&gt;على سبيل المثال، يعمل &lt;strong&gt;RAID 1&lt;/strong&gt; على الاحتفاظ بنسخة متطابقة من البيانات على قرصين.&lt;/p&gt;
&lt;p&gt;لكن من المهم معرفة أن RAID لا يعتبر نسخة احتياطية كاملة، لأنه لا يحمي من جميع أنواع فقدان البيانات.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;المكونات البرمجية للسيرفر&lt;/h3&gt;
&lt;p&gt;لا تقتصر مكونات السيرفر على الأجزاء المادية، فهناك مجموعة من البرمجيات والخدمات التي تجعل الجهاز قادرًا على تقديم الخدمات للمستخدمين.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;نظام التشغيل&lt;/h4&gt;
&lt;p&gt;نظام التشغيل هو الطبقة الأساسية التي تدير موارد الجهاز وتسمح بتشغيل الخدمات والتطبيقات.&lt;/p&gt;
&lt;p&gt;ومن أشهر أنظمة تشغيل السيرفرات:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;Windows Server&lt;/li&gt;
&lt;li&gt;أنظمة Unix وبعض الأنظمة الأخرى المتخصصة&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: right;"&gt;Web Server&lt;/h4&gt;
&lt;p&gt;وظيفته استقبال طلبات HTTP وHTTPS وتقديم صفحات وملفات المواقع للمستخدمين.&lt;/p&gt;
&lt;p&gt;ومن أشهر برامج خوادم الويب:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Apache&lt;/li&gt;
&lt;li&gt;Nginx&lt;/li&gt;
&lt;li&gt;Microsoft IIS&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: right;"&gt;Database Server&lt;/h4&gt;
&lt;p&gt;مسؤول عن إدارة قواعد البيانات التي تحتوي على معلومات التطبيقات والمواقع.&lt;/p&gt;
&lt;p&gt;ومن أمثلة أنظمة قواعد البيانات:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;li&gt;Microsoft SQL Server&lt;/li&gt;
&lt;li&gt;Oracle Database&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 style="text-align: right;"&gt;Application Server&lt;/h4&gt;
&lt;p&gt;يُستخدم لتشغيل التطبيقات والخدمات البرمجية التي تنفذ العمليات المطلوبة من المستخدمين.&lt;/p&gt;
&lt;p&gt;وقد يتكامل مع Web Server وقاعدة البيانات لتكوين نظام متكامل.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;كيف يعمل السيرفر عند فتح موقع إلكتروني؟&lt;/h3&gt;
&lt;p&gt;لنفترض أنك كتبت عنوان موقع في المتصفح.&lt;/p&gt;
&lt;p&gt;تحدث العملية بصورة مبسطة كالتالي:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. المتصفح يرسل طلبًا&lt;/strong&gt;&amp;nbsp;: جهازك يرسل طلبًا للوصول إلى الموقع.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. يتم تحديد عنوان السيرفر&lt;/strong&gt;&amp;nbsp;: يتم استخدام نظام DNS للمساعدة في تحويل اسم النطاق إلى عنوان IP مناسب.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. يصل الطلب إلى السيرفر&lt;/strong&gt;&amp;nbsp;: يستقبل السيرفر الاتصال من خلال الشبكة.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. تتم معالجة الطلب&lt;/strong&gt;&amp;nbsp;: يقوم Web Server أو التطبيق بمعالجة الطلب، وقد يحتاج إلى الوصول إلى قاعدة البيانات.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. يتم جلب البيانات&lt;/strong&gt;&amp;nbsp;: يتم الحصول على الملفات أو البيانات المطلوبة من التخزين أو قاعدة البيانات.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. إرسال الاستجابة&amp;nbsp;&lt;/strong&gt;: يرسل السيرفر النتيجة إلى جهاز المستخدم.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. عرض الصفحة&lt;/strong&gt;&amp;nbsp;: يقوم المتصفح بعرض المحتوى أمام المستخدم.&lt;/p&gt;
&lt;p&gt;يمكن تصور العملية هكذا:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;المستخدم → DNS → الإنترنت → Firewall/Router → Web Server → Application → Database → Web Server → المستخدم&lt;/strong&gt;&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;أنواع السيرفرات&lt;/h3&gt;
&lt;p&gt;توجد أنواع متعددة من السيرفرات، ويختلف النوع حسب الوظيفة التي يؤديها.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;Web Server : يستضيف المواقع وصفحات الويب.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;Database Server : يدير قواعد البيانات والاستعلامات والبيانات.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;File Server : يوفر تخزين الملفات ومشاركتها بين المستخدمين.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;Mail Server : يتولى إرسال واستقبال البريد الإلكتروني.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;DNS Server : يساعد في ترجمة أسماء النطاقات إلى عناوين IP.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;Application Server : يشغل التطبيقات والخدمات البرمجية.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;Backup Server : يُستخدم لإدارة وحفظ النسخ الاحتياطية للبيانات.&lt;/p&gt;
&lt;p style="text-align: right;"&gt;Virtualization Server : يشغل عدة أجهزة افتراضية Virtual Machines على جهاز فعلي واحد.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;ما هو Rack Server؟&lt;/h3&gt;
&lt;p&gt;في الشركات ومراكز البيانات، يتم تركيب العديد من السيرفرات داخل هيكل يسمى &lt;strong&gt;Rack&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;يساعد الـRack على تنظيم الأجهزة وتسهيل:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;توصيل الشبكات.&lt;/li&gt;
&lt;li&gt;توزيع الطاقة.&lt;/li&gt;
&lt;li&gt;التبريد.&lt;/li&gt;
&lt;li&gt;الصيانة.&lt;/li&gt;
&lt;li&gt;إدارة عدد كبير من السيرفرات.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;وقد تحتوي غرفة السيرفرات على مجموعة من الأجهزة مثل:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Servers + Switches + Routers + Firewalls + Storage + Backup Systems&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;وكل جهاز يؤدي وظيفة محددة ضمن البنية التحتية للشبكة.&lt;/p&gt;
&lt;h3 style="text-align: right;"&gt;لماذا تعتبر السيرفرات مهمة؟&lt;/h3&gt;
&lt;p&gt;أصبحت السيرفرات جزءًا أساسيًا من البنية التحتية الرقمية الحديثة، فهي تشغل المواقع الإلكترونية والتطبيقات وقواعد البيانات والخدمات السحابية وأنظمة الشركات والجامعات وغيرها.&lt;/p&gt;
&lt;p&gt;ومن دون البنية التحتية المناسبة، قد تواجه الخدمات مشاكل مثل بطء الاستجابة أو توقف الخدمة أو فقدان البيانات.&lt;/p&gt;
&lt;p&gt;السيرفر ليس مجرد جهاز كمبيوتر قوي، وإنما &lt;strong&gt;منظومة متكاملة من العتاد والبرمجيات والشبكات&lt;/strong&gt; تعمل معًا لتقديم خدمة للمستخدمين.&lt;/p&gt;
&lt;p&gt;وتشمل أهم مكوناته المعالج، والذاكرة، ووحدات التخزين، واللوحة الأم، وبطاقات الشبكة، ومزودات الطاقة، وأنظمة التبريد، إضافة إلى نظام التشغيل والبرامج والخدمات المختلفة.&lt;/p&gt;
&lt;p&gt;وفهم مكونات السيرفر وطريقة عمله يمثل خطوة أساسية لكل شخص يريد تعلم &lt;strong&gt;إدارة الشبكات، استضافة المواقع، الأمن السيبراني، إدارة الأنظمة، أو الحوسبة السحابية&lt;/strong&gt;.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/995073623078851816/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/what-is-a-server-components-and-how-it-works.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/995073623078851816" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/995073623078851816" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/10/what-is-a-server-components-and-how-it-works.html" rel="alternate" title="ما هو السيرفر؟ شرح شامل للسيرفر ومكوناته وكيف يعمل" type="text/html"/><author><name>سجى الصادق محمد</name><uri>http://www.blogger.com/profile/12113988078953579365</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOjL_gQSy_jIXsR3iEZIqpWwiE-ft2tlydjYYqlQRS1nD5X-guq_0ayCvnZ-L_b9uwnKamyOL3Tg4RmgMqfCP5_UCgHjII1Qm9mKUIHOBT8gBqBjmmQILYafDlYMO4K9t71E4aL7Mctr_4kOYSk91xgwifywsvhdjpZEZBWa1Gh0wgzw/s1600/%D9%A2%D9%A0%D9%A2%D9%A6%D9%A0%D9%A6%D9%A0%D9%A3_%D9%A2%D9%A0%D9%A2%D9%A1%D9%A0%D9%A2.png" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAJGW9VNwFWPJzGqQ1-KTSQsIAXwqBthTTr8nq6FH8JlMzeZg4D2oYuinO8HIQC_SaCBvQ4VlUmw-yoUNM3AOnBP7LSmydATw4Hh2Mv_IO7spL1z9Net5E8uHAR4iywR9jLUBK90jxpp_J3iuWfVwdvm2wdIOJwFMN210kyPDbGJtOOi6nMQQCyEMz8ieX/s72-c/imageedit_1_6113856441.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-6445708854508793518</id><published>2026-10-03T18:31:14.801+03:00</published><updated>2026-10-03T18:31:31.702+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">الصلاحيات و الأدوار Authentication في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipSfM5sdZBaPCh3G0uqXMJ5kPhPjLVd2jGdm9ZkP5GDSTN9kXU7J59m03I0rWA2FshqE44KhHA8qGPWeUdw3NDksSBfD8dGJQsyJsrvG3SYy-RR_m_Y7wR7SUIUev-wY5sJ9-Q7ve4Qo6U3leTlKZXkJdc0_WluKxe5X1oYMCbnsIgtECeSzhuF6LaLzHB/s640/imageedit_1_9637435525.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Authorization في Laravel – الصلاحيات والأدوار وGates وPolicies" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipSfM5sdZBaPCh3G0uqXMJ5kPhPjLVd2jGdm9ZkP5GDSTN9kXU7J59m03I0rWA2FshqE44KhHA8qGPWeUdw3NDksSBfD8dGJQsyJsrvG3SYy-RR_m_Y7wR7SUIUev-wY5sJ9-Q7ve4Qo6U3leTlKZXkJdc0_WluKxe5X1oYMCbnsIgtECeSzhuF6LaLzHB/s1600/imageedit_1_9637435525.webp" title="Authorization في Laravel – الصلاحيات والأدوار وGates وPolicies" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;الصلاحيات والأدوار و Gates و Policies في Laravel&lt;/h3&gt;&lt;p&gt;بعد أن تعلمنا في الدرس الثاني عشر كيفية بناء نظام &lt;strong&gt;Authentication&lt;/strong&gt; وتسجيل المستخدمين وتسجيل الدخول والخروج وحماية المسارات باستخدام &lt;code inline=""&gt;auth&lt;/code&gt; Middleware، وصلنا الآن إلى خطوة مهمة جدًا في بناء التطبيقات الحقيقية، وهي &lt;strong&gt;Authorization&lt;/strong&gt; أو نظام الصلاحيات.&lt;/p&gt;&lt;p&gt;في الدرس السابق تعلمنا الإجابة عن السؤال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;من هو المستخدم؟
&lt;/pre&gt;&lt;p&gt;أما في هذا الدرس فسنتعلم الإجابة عن سؤال مختلف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ماذا يُسمح لهذا المستخدم أن يفعل؟
&lt;/pre&gt;&lt;p&gt;فمثلًا، قد يكون لدينا مستخدمان مسجلان في الموقع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Ahmed
Mohamed
&lt;/pre&gt;&lt;p&gt;كلاهما يستطيع تسجيل الدخول والوصول إلى لوحة المستخدم، لكن ربما يكون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Ahmed = Administrator
Mohamed = User
&lt;/pre&gt;&lt;p&gt;وبالتالي قد نسمح لـ Ahmed بإدارة المستخدمين وحذف المقالات، بينما يستطيع Mohamed قراءة المقالات وإنشاء مقالاته الخاصة فقط.&lt;/p&gt;&lt;p&gt;وهنا يظهر مفهوم &lt;strong&gt;Authorization&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Laravel يوفر نظام Authorization متكاملًا يعتمد بشكل أساسي على &lt;strong&gt;Gates&lt;/strong&gt; و&lt;strong&gt;Policies&lt;/strong&gt; لتنظيم قواعد السماح والمنع، ويمكن استخدام هذه القواعد داخل Controllers وRoutes وBlade وغيرها.&lt;/p&gt;&lt;h3&gt;ما هو Authorization؟&lt;/h3&gt;&lt;p&gt;Authorization يعني تحديد العمليات التي يُسمح للمستخدم بتنفيذها بعد أن تم التعرف على هويته.&lt;/p&gt;&lt;p&gt;بمعنى آخر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
= من أنت؟

Authorization
= ماذا يمكنك أن تفعل؟
&lt;/pre&gt;&lt;p&gt;لنفترض أن المستخدم قام بتسجيل الدخول بنجاح:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Login
 ↓
Authentication
 ↓
User authenticated
&lt;/pre&gt;&lt;p&gt;هذا لا يعني تلقائيًا أنه يستطيع تنفيذ كل شيء.&lt;/p&gt;&lt;p&gt;بعد ذلك نحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authorization
 ↓
هل يستطيع تعديل المقال؟
هل يستطيع حذفه؟
هل يستطيع إدارة المستخدمين؟
هل يستطيع الوصول إلى لوحة الإدارة؟
&lt;/pre&gt;&lt;h3&gt;الفرق بين Authentication وAuthorization&lt;/h3&gt;&lt;p&gt;من المهم جدًا أن تحفظ هذا الفرق لأنك ستستخدم المفهومين باستمرار في Laravel.&lt;/p&gt;&lt;h3&gt;Authentication&lt;/h3&gt;&lt;p&gt;يتحقق من هوية المستخدم.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل البريد الإلكتروني وكلمة المرور صحيحتان؟
هل المستخدم مسجل الدخول؟
&lt;/pre&gt;&lt;p&gt;ونستخدم في Laravel أشياء مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::check();
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::user();
&lt;/pre&gt;&lt;h3&gt;Authorization&lt;/h3&gt;&lt;p&gt;يتحقق من صلاحيات المستخدم.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع هذا المستخدم حذف المقال؟
هل يستطيع تعديل هذا المقال؟
هل يستطيع فتح لوحة الإدارة؟
&lt;/pre&gt;&lt;p&gt;وبالتالي يمكن أن تكون العملية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
Login
 ↓
Authentication
 ↓
Authenticated
 ↓
Authorization
 ↓
Allowed / Denied
&lt;/pre&gt;&lt;p&gt;Laravel نفسه يوضح أن Guards وProviders تخص Authentication، ولا ينبغي الخلط بينها وبين Roles وPermissions الخاصة بتحديد ما يمكن للمستخدم فعله.&lt;/p&gt;&lt;h3&gt;مثال بسيط على Authorization&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا مقالًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article #15
Title: تعلم Laravel
Author: Ahmed
&lt;/pre&gt;&lt;p&gt;ولدينا مستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Mohamed
&lt;/pre&gt;&lt;p&gt;محمد يستطيع تسجيل الدخول، أي أن Authentication ناجح.&lt;/p&gt;&lt;p&gt;لكن عندما يحاول تعديل المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Mohamed
   ↓
Edit Article #15
   ↓
Authorization
   ↓
هل محمد هو صاحب المقال؟
   ↓
لا
   ↓
Denied
&lt;/pre&gt;&lt;p&gt;بينما إذا كان:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Ahmed
   ↓
Edit Article #15
   ↓
Authorization
   ↓
هل Ahmed هو صاحب المقال؟
   ↓
نعم
   ↓
Allowed
&lt;/pre&gt;&lt;p&gt;وهذه هي الفكرة الأساسية التي سنبني عليها الدرس.&lt;/p&gt;&lt;h3&gt;هل Laravel يحتوي على نظام Roles وPermissions جاهز؟&lt;/h3&gt;&lt;p&gt;هذه نقطة مهمة جدًا.&lt;/p&gt;&lt;p&gt;Laravel يوفر &lt;strong&gt;Authorization&lt;/strong&gt; من خلال Gates وPolicies، لكنه لا يفرض عليك نظامًا واحدًا جاهزًا لإدارة Roles وPermissions مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
Editor
Author
User
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;create-post
edit-post
delete-post
manage-users
&lt;/pre&gt;&lt;p&gt;يمكنك بناء نظام الأدوار والصلاحيات داخل تطبيقك بالطريقة المناسبة، أو استخدام حزمة خارجية متخصصة عندما يحتاج المشروع إلى نظام متقدم.&lt;/p&gt;&lt;p&gt;أما الأدوات الأساسية التي يوفرها Laravel نفسه فهي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gates
Policies
Authorization Middleware
Blade Authorization
User can()
&lt;/pre&gt;&lt;p&gt;وتوضح وثائق Laravel أن Gates مناسبة خصوصًا للقواعد العامة التي لا ترتبط مباشرةً بموديل معين، بينما Policies مناسبة لتنظيم الصلاحيات المرتبطة بـ Model أو Resource.&lt;/p&gt;&lt;h3&gt;ما هي Gates في Laravel؟&lt;/h3&gt;&lt;p&gt;الـ &lt;strong&gt;Gate&lt;/strong&gt; عبارة عن قاعدة Authorization تحدد ما إذا كان المستخدم يستطيع تنفيذ عملية معينة.&lt;/p&gt;&lt;p&gt;يمكن التفكير فيها كأنها سؤال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع هذا المستخدم تنفيذ هذه العملية؟
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع المستخدم فتح لوحة الإدارة؟
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع المستخدم إنشاء مقال؟
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع المستخدم حذف المقال؟
&lt;/pre&gt;&lt;h3&gt;إنشاء Gate&lt;/h3&gt;&lt;p&gt;في Laravel 13 يمكن تعريف Gates داخل &lt;code inline=""&gt;AppServiceProvider&lt;/code&gt; باستخدام &lt;code inline=""&gt;Gate&lt;/code&gt; Facade.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Providers;

use App\Models\User;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Gate::define('access-admin', function (User $user) {
            return $user-&amp;gt;is_admin;
        });
    }
}
&lt;/pre&gt;&lt;p&gt;هنا أنشأنا Gate باسم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;access-admin
&lt;/pre&gt;&lt;p&gt;ويتم التحقق من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;is_admin
&lt;/pre&gt;&lt;p&gt;إذا كانت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;true
&lt;/pre&gt;&lt;p&gt;فالمستخدم يستطيع الوصول.&lt;/p&gt;&lt;p&gt;إذا كانت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;false
&lt;/pre&gt;&lt;p&gt;فسيتم رفض العملية.&lt;/p&gt;&lt;h3&gt;تجربة Gate باستخدام allows&lt;/h3&gt;&lt;p&gt;بعد إنشاء Gate يمكننا التحقق منه باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate::allows('access-admin')
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Support\Facades\Gate;

if (Gate::allows('access-admin')) {
    return 'Welcome Admin';
}
&lt;/pre&gt;&lt;p&gt;Laravel يوفر عدة طرق لفحص الصلاحيات مثل &lt;code inline=""&gt;allows&lt;/code&gt; و&lt;code inline=""&gt;denies&lt;/code&gt; و&lt;code inline=""&gt;authorize&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;استخدام Gate::authorize&lt;/h3&gt;&lt;p&gt;بدل كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (! Gate::allows('access-admin')) {
    abort(403);
}
&lt;/pre&gt;&lt;p&gt;يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate::authorize('access-admin');
&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم غير مصرح له، يقوم Laravel بإطلاق &lt;code inline=""&gt;AuthorizationException&lt;/code&gt; والتي تتحول إلى استجابة HTTP من نوع &lt;code inline=""&gt;403&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function index()
{
    Gate::authorize('access-admin');

    return view('admin.dashboard');
}
&lt;/pre&gt;&lt;p&gt;وهذه طريقة نظيفة جدًا عندما تكون العملية يجب أن تتوقف مباشرة إذا لم يكن المستخدم مخولًا.&lt;/p&gt;&lt;h3&gt;ما معنى HTTP 403؟&lt;/h3&gt;&lt;p&gt;عندما ترى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;403 Forbidden
&lt;/pre&gt;&lt;p&gt;فهذا يعني أن الطلب وصل إلى التطبيق، لكن المستخدم غير مخول بتنفيذ العملية المطلوبة.&lt;/p&gt;&lt;p&gt;وهذا مختلف عن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;401 Unauthorized
&lt;/pre&gt;&lt;p&gt;في السياقات التي تتعلق بالمصادقة.&lt;/p&gt;&lt;p&gt;في تطبيق Laravel، عندما يفشل Authorization عبر Gate أو Policy بطريقة مناسبة، يمكن أن تحصل على استجابة &lt;code inline=""&gt;403&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;متى نستخدم Gates؟&lt;/h3&gt;&lt;p&gt;Gates مناسبة جدًا للعمليات العامة التي لا ترتبط بسجل Model معين.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;الوصول إلى لوحة الإدارة
الوصول إلى صفحة الإحصائيات
عرض إعدادات النظام
إدارة النظام
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate::define('access-admin', function (User $user) {
    return $user-&amp;gt;is_admin;
});
&lt;/pre&gt;&lt;p&gt;لكن ماذا لو أردنا التعامل مع مقال معين؟&lt;/p&gt;&lt;p&gt;هنا تأتي &lt;strong&gt;Policies&lt;/strong&gt;.&lt;/p&gt;&lt;h3&gt;ما هي Policies؟&lt;/h3&gt;&lt;p&gt;الـ &lt;strong&gt;Policy&lt;/strong&gt; عبارة عن Class مخصص لتنظيم Authorization الخاص بـ Model أو Resource معين.&lt;/p&gt;&lt;p&gt;مثلًا لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;يمكننا إنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticlePolicy
&lt;/pre&gt;&lt;p&gt;وتضع داخلها قواعد مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;view
create
update
delete
&lt;/pre&gt;&lt;p&gt;Laravel يصف Policies بأنها Classes تنظم منطق Authorization حول Model أو Resource محدد.&lt;/p&gt;&lt;h3&gt;إنشاء Policy&lt;/h3&gt;&lt;p&gt;يمكننا استخدام Artisan:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:policy ArticlePolicy --model=Article
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء Policy داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Policies/ArticlePolicy.php
&lt;/pre&gt;&lt;p&gt;وعند استخدام &lt;code inline=""&gt;--model&lt;/code&gt; يمكن لـ Laravel إنشاء بنية مرتبطة بالـ Model لتسهيل كتابة قواعد Authorization.&lt;/p&gt;&lt;h3&gt;شكل ArticlePolicy&lt;/h3&gt;&lt;p&gt;يمكن أن تبدو Policy بهذا الشكل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Policies;

use App\Models\Article;
use App\Models\User;

class ArticlePolicy
{
    public function view(User $user, Article $article): bool
    {
        return true;
    }

    public function create(User $user): bool
    {
        return true;
    }

    public function update(User $user, Article $article): bool
    {
        return $user-&amp;gt;id === $article-&amp;gt;user_id;
    }

    public function delete(User $user, Article $article): bool
    {
        return $user-&amp;gt;id === $article-&amp;gt;user_id;
    }
}
&lt;/pre&gt;&lt;p&gt;لاحظ أن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;update()
&lt;/pre&gt;&lt;p&gt;تستقبل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User $user
Article $article
&lt;/pre&gt;&lt;p&gt;وبذلك تستطيع مقارنة المستخدم بالمستخدم الذي يملك المقال.&lt;/p&gt;&lt;h3&gt;فكرة مهمة: صاحب المورد&lt;/h3&gt;&lt;p&gt;لنفترض أن جدول &lt;code inline=""&gt;articles&lt;/code&gt; يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
title
content
user_id
&lt;/pre&gt;&lt;p&gt;وأن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;يشير إلى صاحب المقال.&lt;/p&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return $user-&amp;gt;id === $article-&amp;gt;user_id;
&lt;/pre&gt;&lt;p&gt;وهذا يعني:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إذا كان المستخدم الحالي هو صاحب المقال
→ يسمح له بالتعديل

إذا لم يكن صاحب المقال
→ يمنع من التعديل
&lt;/pre&gt;&lt;h3&gt;Policy Method للتعديل&lt;/h3&gt;&lt;p&gt;يمكن أن يكون لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(User $user, Article $article): bool
{
    return $user-&amp;gt;id === $article-&amp;gt;user_id;
}
&lt;/pre&gt;&lt;p&gt;هذه القاعدة تقول:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;المستخدم يستطيع تعديل المقال إذا كان هو صاحبه.&lt;/p&gt;&lt;/blockquote&gt;&lt;h3&gt;Policy Method للحذف&lt;/h3&gt;&lt;p&gt;وبالمثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function delete(User $user, Article $article): bool
{
    return $user-&amp;gt;id === $article-&amp;gt;user_id;
}
&lt;/pre&gt;&lt;p&gt;وبذلك لا يستطيع مستخدم عادي حذف مقال مستخدم آخر.&lt;/p&gt;&lt;h3&gt;ماذا لو كان المدير يستطيع تعديل كل المقالات؟&lt;/h3&gt;&lt;p&gt;هنا يمكننا إضافة Role بسيط للمستخدم.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users

id
name
email
password
role
&lt;/pre&gt;&lt;p&gt;وتكون قيمة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;admin
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;editor
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user
&lt;/pre&gt;&lt;p&gt;يمكن أن تصبح Policy:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(User $user, Article $article): bool
{
    return $user-&amp;gt;role === 'admin'
        || $user-&amp;gt;id === $article-&amp;gt;user_id;
}
&lt;/pre&gt;&lt;p&gt;الآن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
 ↓
يستطيع تعديل أي مقال

User
 ↓
يستطيع تعديل مقاله فقط
&lt;/pre&gt;&lt;p&gt;وهذا مثال بسيط جدًا على دمج &lt;strong&gt;Roles&lt;/strong&gt; مع &lt;strong&gt;Policies&lt;/strong&gt;.&lt;/p&gt;&lt;h3&gt;لماذا لا نضع هذه الشروط داخل Controller؟&lt;/h3&gt;&lt;p&gt;قد يفكر المبتدئ في كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(Article $article)
{
    if (
        auth()-&amp;gt;user()-&amp;gt;role !== 'admin'
        &amp;amp;&amp;amp; auth()-&amp;gt;id() !== $article-&amp;gt;user_id
    ) {
        abort(403);
    }

    // update...
}
&lt;/pre&gt;&lt;p&gt;قد يعمل هذا الكود، لكن المشكلة تظهر عندما يصبح التطبيق كبيرًا.&lt;/p&gt;&lt;p&gt;قد تضطر إلى تكرار نفس الشرط في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticleController
CommentController
AdminController
Blade
API
Tests
&lt;/pre&gt;&lt;p&gt;وبمرور الوقت تصبح قواعد الصلاحيات موزعة في أماكن كثيرة.&lt;/p&gt;&lt;p&gt;هنا تظهر أهمية Policy.&lt;/p&gt;&lt;p&gt;بدل تكرار القاعدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;من يستطيع تعديل المقال؟
&lt;/pre&gt;&lt;p&gt;نضعها في مكان واحد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticlePolicy
&lt;/pre&gt;&lt;p&gt;وهذا يجعل الكود أكثر تنظيمًا وأسهل في الاختبار والصيانة.&lt;/p&gt;&lt;h3&gt;ربط Policy مع Model&lt;/h3&gt;&lt;p&gt;Laravel 13 يستطيع اكتشاف Policies تلقائيًا عندما تتبع أسماء الملفات والمجلدات conventions المعتادة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Models/Article.php
app/Policies/ArticlePolicy.php
&lt;/pre&gt;&lt;p&gt;بحيث يتوافق اسم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;مع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticlePolicy
&lt;/pre&gt;&lt;p&gt;وتوضح وثائق Laravel أن Policy Discovery يعتمد على هذه conventions، ويمكن أيضًا تسجيل Policy يدويًا عند الحاجة.&lt;/p&gt;&lt;h3&gt;استخدام Policy من خلال User Model&lt;/h3&gt;&lt;p&gt;بعد إعداد Policy، يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;can('update', $article)
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if ($user-&amp;gt;can('update', $article)) {
    // يستطيع التعديل
}
&lt;/pre&gt;&lt;p&gt;أو باستخدام المستخدم الحالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (auth()-&amp;gt;user()-&amp;gt;can('update', $article)) {
    // يسمح بالتعديل
}
&lt;/pre&gt;&lt;p&gt;وهذا يجعل قراءة الكود سهلة جدًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع هذا المستخدم تحديث هذا المقال؟
&lt;/pre&gt;&lt;h3&gt;استخدام can داخل Controller&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(Article $article)
{
    if (! auth()-&amp;gt;user()-&amp;gt;can('update', $article)) {
        abort(403);
    }

    // Update article...
}
&lt;/pre&gt;&lt;p&gt;يمكن أن تعمل هذه الطريقة.&lt;/p&gt;&lt;p&gt;لكن Laravel يوفر طريقة أنظف باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;authorize()
&lt;/pre&gt;&lt;p&gt;أو &lt;code inline=""&gt;Gate&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;استخدام authorize داخل Controller&lt;/h3&gt;&lt;p&gt;يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$this-&amp;gt;authorize('update', $article);
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(Article $article)
{
    $this-&amp;gt;authorize('update', $article);

    // Update article...
}
&lt;/pre&gt;&lt;p&gt;إذا لم يكن المستخدم مخولًا، يتم إيقاف العملية والاستجابة بحالة Authorization المناسبة.&lt;/p&gt;&lt;h3&gt;استخدام Policy مع Resource Controller&lt;/h3&gt;&lt;p&gt;وهنا نعود إلى ما تعلمناه في الدرس الخامس.&lt;/p&gt;&lt;p&gt;إذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::resource('articles', ArticleController::class);
&lt;/pre&gt;&lt;p&gt;فيمكننا تنظيم العمليات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;index
create
store
show
edit
update
destroy
&lt;/pre&gt;&lt;p&gt;مع Policy:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;viewAny
view
create
update
delete
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticleController@update
        ↓
ArticlePolicy@update
        ↓
Allowed / Denied
&lt;/pre&gt;&lt;p&gt;وهذه بنية ممتازة لتطبيقات CRUD.&lt;/p&gt;&lt;h3&gt;Authorization باستخدام Middleware&lt;/h3&gt;&lt;p&gt;يمكن أيضًا تطبيق Authorization على Route باستخدام Middleware.&lt;/p&gt;&lt;p&gt;مثلًا يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::put('/articles/{article}', [ArticleController::class, 'update'])
    -&amp;gt;middleware('can:update,article');
&lt;/pre&gt;&lt;p&gt;الفكرة هنا أن Laravel سيتحقق من قدرة المستخدم على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;update
&lt;/pre&gt;&lt;p&gt;للمقال الموجود في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;article
&lt;/pre&gt;&lt;p&gt;قبل تنفيذ Controller.&lt;/p&gt;&lt;p&gt;وهذا مفيد عندما تريد وضع شرط الصلاحية مباشرةً على Route.&lt;/p&gt;&lt;h3&gt;الفرق بين auth وcan Middleware&lt;/h3&gt;&lt;p&gt;في الدرس السابق تعلمنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;-&amp;gt;middleware('auth')
&lt;/pre&gt;&lt;p&gt;وهذا يعني:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل المستخدم مسجل الدخول؟
&lt;/pre&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;-&amp;gt;middleware('can:update,article')
&lt;/pre&gt;&lt;p&gt;فالمعنى هو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل المستخدم مخول بتحديث هذا المقال؟
&lt;/pre&gt;&lt;p&gt;إذن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;auth
 ↓
Authentication

can
 ↓
Authorization
&lt;/pre&gt;&lt;h3&gt;Authorization داخل Blade&lt;/h3&gt;&lt;p&gt;من المهم ألا تعرض أزرار العمليات التي لا يستطيع المستخدم تنفيذها.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@can('update', $article)
    &amp;lt;a href="{{ route('articles.edit', $article) }}"&amp;gt;
        تعديل
    &amp;lt;/a&amp;gt;
@endcan
&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم يستطيع التعديل، يظهر الزر.&lt;/p&gt;&lt;p&gt;إذا لم يكن يستطيع، لا يظهر.&lt;/p&gt;&lt;h3&gt;زر الحذف&lt;/h3&gt;&lt;p&gt;يمكن أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@can('delete', $article)
    &amp;lt;form method="POST" action="{{ route('articles.destroy', $article) }}"&amp;gt;
        @csrf
        @method('DELETE')

        &amp;lt;button type="submit"&amp;gt;
            حذف
        &amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
@endcan
&lt;/pre&gt;&lt;p&gt;هذا يجعل الواجهة أكثر ذكاءً.&lt;/p&gt;&lt;p&gt;لكن انتبه إلى نقطة مهمة:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;إخفاء الزر ليس حماية كافية.&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;حتى لو لم يظهر زر Delete، يمكن للمستخدم محاولة إرسال Request يدويًا إلى Route.&lt;/p&gt;&lt;p&gt;لذلك يجب أن تكون Policy أو Authorization موجودة على الخادم أيضًا.&lt;/p&gt;&lt;h3&gt;@cannot و@canany&lt;/h3&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@cannot('update', $article)
    &amp;lt;p&amp;gt;لا يمكنك تعديل هذا المقال.&amp;lt;/p&amp;gt;
@endcannot
&lt;/pre&gt;&lt;p&gt;كما يمكن التحقق من عدة صلاحيات باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@canany(['update', 'delete'], $article)
    &amp;lt;p&amp;gt;لديك صلاحية لإدارة المقال.&amp;lt;/p&amp;gt;
@endcanany
&lt;/pre&gt;&lt;p&gt;Laravel يوفر توجيهات Blade مخصصة لفحص Authorization مثل &lt;code inline=""&gt;@can&lt;/code&gt; و&lt;code inline=""&gt;@cannot&lt;/code&gt; و&lt;code inline=""&gt;@canany&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;بناء نظام Roles بسيط&lt;/h3&gt;&lt;p&gt;لنفترض أن مشروعنا يحتاج إلى ثلاثة أدوار:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;admin
editor
user
&lt;/pre&gt;&lt;p&gt;يمكن إضافة عمود إلى جدول &lt;code inline=""&gt;users&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;ننشيء Migration:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration add_role_to_users_table --table=users
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Schema::table('users', function (Blueprint $table) {
    $table-&amp;gt;string('role')-&amp;gt;default('user');
});
&lt;/pre&gt;&lt;p&gt;بعد ذلك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;الآن كل مستخدم يمكن أن يمتلك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role = user
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role = editor
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role = admin
&lt;/pre&gt;&lt;h3&gt;التحقق من Role&lt;/h3&gt;&lt;p&gt;يمكنك كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (auth()-&amp;gt;user()-&amp;gt;role === 'admin') {
    // Admin
}
&lt;/pre&gt;&lt;p&gt;لكن الأفضل مع نمو التطبيق أن تجعل هذا المنطق أكثر تنظيمًا.&lt;/p&gt;&lt;p&gt;مثلًا داخل User Model:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function isAdmin(): bool
{
    return $this-&amp;gt;role === 'admin';
}
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (auth()-&amp;gt;user()-&amp;gt;isAdmin()) {
    // Admin
}
&lt;/pre&gt;&lt;p&gt;هذا يجعل قراءة الكود أسهل.&lt;/p&gt;&lt;h3&gt;استخدام Role داخل Gate&lt;/h3&gt;&lt;p&gt;يمكننا الآن بناء Gate:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate::define('access-admin', function (User $user) {
    return $user-&amp;gt;isAdmin();
});
&lt;/pre&gt;&lt;p&gt;ثم في Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate::authorize('access-admin');
&lt;/pre&gt;&lt;p&gt;أصبح لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
role
 ↓
isAdmin()
 ↓
Gate
 ↓
Admin Dashboard
&lt;/pre&gt;&lt;h3&gt;Roles وPolicies معًا&lt;/h3&gt;&lt;p&gt;في تطبيق المقالات، يمكن أن تكون القاعدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
→ يستطيع إدارة جميع المقالات

Editor
→ يستطيع تعديل المقالات

Author
→ يستطيع تعديل مقالاته

User
→ يستطيع القراءة فقط
&lt;/pre&gt;&lt;p&gt;ويمكن أن تكون Policy:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(User $user, Article $article): bool
{
    if ($user-&amp;gt;role === 'admin') {
        return true;
    }

    if ($user-&amp;gt;role === 'editor') {
        return true;
    }

    return $user-&amp;gt;id === $article-&amp;gt;user_id;
}
&lt;/pre&gt;&lt;p&gt;هذه طريقة بسيطة لفهم العلاقة بين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Role
+
Resource
+
Action
&lt;/pre&gt;&lt;h3&gt;ماذا لو أصبح المشروع كبيرًا؟&lt;/h3&gt;&lt;p&gt;في المشاريع الكبيرة قد يصبح لديك عشرات الصلاحيات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.create
articles.update
articles.delete

users.view
users.create
users.update
users.delete

categories.create
categories.update
categories.delete
&lt;/pre&gt;&lt;p&gt;وقد يكون المستخدم لديه أكثر من Role.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Ahmed
Roles:
- editor
- author
&lt;/pre&gt;&lt;p&gt;هنا قد يكون من الأفضل تصميم نظام أكثر مرونة باستخدام جداول مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
roles
permissions
role_user
permission_role
&lt;/pre&gt;&lt;p&gt;أو استخدام حزمة متخصصة لإدارة Roles وPermissions.&lt;/p&gt;&lt;p&gt;الفكرة المهمة في هذا الدرس هي فهم &lt;strong&gt;Authorization في Laravel&lt;/strong&gt;، وليس بناء نظام Enterprise كامل لإدارة الصلاحيات.&lt;/p&gt;&lt;h3&gt;Policy أم Gate؟&lt;/h3&gt;&lt;p&gt;هذه من أهم النقاط في الدرس.&lt;/p&gt;&lt;h3&gt;استخدم Gate عندما تكون القاعدة عامة&lt;/h3&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع المستخدم فتح لوحة الإدارة؟
&lt;/pre&gt;&lt;p&gt;يمكن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate::define('access-admin', ...);
&lt;/pre&gt;&lt;h3&gt;استخدم Policy عندما تكون القاعدة مرتبطة بـ Model&lt;/h3&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل يستطيع المستخدم تعديل هذا المقال؟
&lt;/pre&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticlePolicy
&lt;/pre&gt;&lt;p&gt;لأن العملية مرتبطة بـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;وتلخص وثائق Laravel الفرق بأن Gates مناسبة لقواعد Authorization العامة، بينما Policies تنظّم قواعد مرتبطة بموديل أو Resource معين.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال عملي كامل&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنقم ببناء نظام بسيط للمقالات.&lt;/p&gt;&lt;p&gt;لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
Article
&lt;/pre&gt;&lt;p&gt;والمقال يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
title
content
user_id
&lt;/pre&gt;&lt;p&gt;لدينا أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users.role
&lt;/pre&gt;&lt;p&gt;وقيمته:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;admin
user
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;إنشاء Policy&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;نفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:policy ArticlePolicy --model=Article
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Policies;

use App\Models\Article;
use App\Models\User;

class ArticlePolicy
{
    public function update(User $user, Article $article): bool
    {
        return $user-&amp;gt;role === 'admin'
            || $user-&amp;gt;id === $article-&amp;gt;user_id;
    }

    public function delete(User $user, Article $article): bool
    {
        return $user-&amp;gt;role === 'admin'
            || $user-&amp;gt;id === $article-&amp;gt;user_id;
    }
}
&lt;/pre&gt;&lt;p&gt;الآن لدينا قاعدة واضحة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
→ Update any article
→ Delete any article

Owner
→ Update own article
→ Delete own article

Other user
→ Cannot update
→ Cannot delete
&lt;/pre&gt;&lt;h3&gt;Controller&lt;/h3&gt;&lt;p&gt;داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticleController
&lt;/pre&gt;&lt;p&gt;يمكننا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function update(Request $request, Article $article)
{
    $this-&amp;gt;authorize('update', $article);

    $validated = $request-&amp;gt;validate([
        'title' =&amp;gt; ['required', 'string', 'max:255'],
        'content' =&amp;gt; ['required', 'string'],
    ]);

    $article-&amp;gt;update($validated);

    return redirect()
        -&amp;gt;route('articles.show', $article)
        -&amp;gt;with('success', 'تم تحديث المقال بنجاح.');
}
&lt;/pre&gt;&lt;p&gt;لاحظ ترتيب العملية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Request
 ↓
Authorization
 ↓
Validation
 ↓
Update
 ↓
Redirect
&lt;/pre&gt;&lt;p&gt;وهذا أفضل من تحديث البيانات قبل التحقق من الصلاحية.&lt;/p&gt;&lt;h3&gt;Blade&lt;/h3&gt;&lt;p&gt;في صفحة المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@can('update', $article)
    &amp;lt;a href="{{ route('articles.edit', $article) }}"&amp;gt;
        تعديل المقال
    &amp;lt;/a&amp;gt;
@endcan

@can('delete', $article)
    &amp;lt;form method="POST" action="{{ route('articles.destroy', $article) }}"&amp;gt;
        @csrf
        @method('DELETE')

        &amp;lt;button type="submit"&amp;gt;
            حذف المقال
        &amp;lt;/button&amp;gt;
    &amp;lt;/form&amp;gt;
@endcan
&lt;/pre&gt;&lt;p&gt;الآن تظهر العمليات المناسبة للمستخدم.&lt;/p&gt;&lt;h3&gt;ماذا يحدث عند محاولة الوصول بشكل مباشر؟&lt;/h3&gt;&lt;p&gt;لنفترض أن مستخدمًا غير مصرح له حاول الوصول إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/articles/15/edit
&lt;/pre&gt;&lt;p&gt;حتى لو لم يظهر له زر التعديل، يمكنه كتابة الرابط يدويًا.&lt;/p&gt;&lt;p&gt;لكن Controller يستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$this-&amp;gt;authorize('update', $article);
&lt;/pre&gt;&lt;p&gt;وبالتالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Request
 ↓
Controller
 ↓
Policy
 ↓
Denied
 ↓
403 Forbidden
&lt;/pre&gt;&lt;p&gt;وهذه هي الحماية الحقيقية.&lt;/p&gt;&lt;h3&gt;Gate Responses&lt;/h3&gt;&lt;p&gt;في بعض الحالات قد لا تريد مجرد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;true
false
&lt;/pre&gt;&lt;p&gt;بل تريد رسالة توضّح سبب الرفض.&lt;/p&gt;&lt;p&gt;Laravel يسمح بإرجاع &lt;code inline=""&gt;Response&lt;/code&gt; من Gate، بحيث يمكن تحديد سبب الرفض.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Auth\Access\Response;

Gate::define('access-admin', function (User $user) {
    return $user-&amp;gt;isAdmin()
        ? Response::allow()
        : Response::deny('يجب أن تكون مديرًا للوصول إلى هذه الصفحة.');
});
&lt;/pre&gt;&lt;p&gt;وهذا مفيد عندما تريد تقديم سبب واضح للمنع.&lt;/p&gt;&lt;h3&gt;Laravel 13 وPHP Attributes في Authorization&lt;/h3&gt;&lt;p&gt;من الإضافات المهمة في Laravel 13 توسيع استخدام PHP Attributes، ومنها &lt;code inline=""&gt;#[Authorize]&lt;/code&gt; في Controllers.&lt;/p&gt;&lt;p&gt;مثلًا يمكن تعريف Authorization مباشرةً على Method:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Routing\Attributes\Controllers\Authorize;

#[Authorize('delete', 'article')]
public function destroy(Article $article)
{
    // ...
}
&lt;/pre&gt;&lt;p&gt;وتوضح ملاحظات إصدار Laravel 13 أن &lt;code inline=""&gt;#[Authorize]&lt;/code&gt; يمكن استخدامها لتطبيق Policy checks مباشرة على Controller methods.&lt;/p&gt;&lt;p&gt;هذه الطريقة مفيدة عندما تريد كتابة قواعد Middleware وAuthorization بطريقة declarative بالقرب من Controller Method.&lt;/p&gt;&lt;p&gt;لكن كمبتدئ، من الأفضل أولًا فهم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$this-&amp;gt;authorize()
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Gate
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Policy
&lt;/pre&gt;&lt;p&gt;قبل الانتقال إلى الأساليب المتقدمة.&lt;/p&gt;&lt;h3&gt;Authorization داخل Form Request&lt;/h3&gt;&lt;p&gt;في الدرس السابع تعلمنا &lt;strong&gt;Form Requests&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;ومن المفيد معرفة أن Form Request يحتوي أيضًا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;authorize()
&lt;/pre&gt;&lt;p&gt;يمكن استخدامه للتحقق من أن المستخدم مسموح له بتنفيذ الطلب قبل تنفيذ منطق الـ Controller. وتوضح وثائق Laravel أن &lt;code inline=""&gt;authorize()&lt;/code&gt; في Form Request يمكنها استخدام المستخدم الحالي وGates أو Policies لاتخاذ قرار السماح.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function authorize(): bool
{
    $article = Article::find($this-&amp;gt;route('article'));

    return $article
        &amp;amp;&amp;amp; $this-&amp;gt;user()-&amp;gt;can('update', $article);
}
&lt;/pre&gt;&lt;p&gt;وهكذا يصبح Form Request مسؤولًا عن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authorization
+
Validation
&lt;/pre&gt;&lt;p&gt;في مكان واحد.&lt;/p&gt;&lt;h3&gt;Authorization مع الاختبارات&lt;/h3&gt;&lt;p&gt;بعد بناء نظام الصلاحيات يجب أن نختبره.&lt;/p&gt;&lt;p&gt;يمكن أن يكون لدينا اختبار يتأكد من أن صاحب المقال يستطيع التعديل، بينما مستخدم آخر لا يستطيع.&lt;/p&gt;&lt;p&gt;Laravel يوفر &lt;code inline=""&gt;actingAs()&lt;/code&gt; داخل HTTP Tests لتسجيل مستخدم بشكل مصادق عليه أثناء الاختبار.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::factory()-&amp;gt;create();

$response = $this-&amp;gt;actingAs($user)
    -&amp;gt;get('/dashboard');
&lt;/pre&gt;&lt;p&gt;وفي اختبارات Authorization يمكننا إنشاء مستخدمين مختلفين واختبار السيناريوهات.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin → Allowed
Owner → Allowed
Other User → Forbidden
Guest → Redirect to Login
&lt;/pre&gt;&lt;h3&gt;أخطاء شائعة في Authorization&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;الاعتماد على إخفاء الأزرار فقط&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;هذا خطأ.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@if ($user-&amp;gt;isAdmin())
    &amp;lt;button&amp;gt;Delete&amp;lt;/button&amp;gt;
@endif
&lt;/pre&gt;&lt;p&gt;هذا يحسن الواجهة، لكنه لا يحمي Route وحده.&lt;/p&gt;&lt;p&gt;يجب أن تكون الحماية على الخادم أيضًا&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخلط بين auth وauthorization&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;-&amp;gt;middleware('auth')
&lt;/pre&gt;&lt;p&gt;يعني أن المستخدم مسجل الدخول.&lt;/p&gt;&lt;p&gt;لا يعني أنه يستطيع تنفيذ كل العمليات.&lt;/p&gt;&lt;p&gt;قد تحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;auth
+
Policy
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;وضع كل الصلاحيات داخل Controller&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;عندما يصبح Controller مليئًا بشروط مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (...)
&lt;/pre&gt;&lt;p&gt;قد يكون الوقت مناسبًا لنقل قواعد Authorization إلى Policies أو Gates.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تكرار نفس القواعد&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا وجدت نفس الشرط يتكرر في عدة Controllers، فهذه إشارة إلى أن القاعدة قد تكون أفضل داخل Policy أو Gate.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;عدم اختبار المستخدم غير المصرح له&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لا تختبر فقط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
&lt;/pre&gt;&lt;p&gt;اختبر أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Guest
User
Owner
Other User
Admin
&lt;/pre&gt;&lt;p&gt;بحسب تصميم التطبيق.&lt;/p&gt;&lt;h3&gt;أفضل الممارسات&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;استخدم Authentication وAuthorization بشكل منفصل&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;فكر دائمًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
→ من أنت؟

Authorization
→ ماذا يمكنك أن تفعل؟
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;استخدم Policies مع Models&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كانت القاعدة مرتبطة بـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
Comment
Order
Invoice
&lt;/pre&gt;&lt;p&gt;فغالبًا ستكون Policy مناسبة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;استخدم Gates للقواعد العامة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;access-admin
view-reports
manage-settings
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;لا تعتمد على الواجهة فقط&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إخفاء الزر لا يعني أن العملية محمية.&lt;/p&gt;&lt;p&gt;الحماية الحقيقية يجب أن تكون في Backend.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;اجعل الصلاحيات قابلة للاختبار&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;كل قاعدة Authorization مهمة يجب أن يكون من السهل اختبارها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تمرين عملي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;حان الآن دورك لتطبيق ما تعلمته.&lt;/p&gt;&lt;p&gt;أنشئ نظام مقالات يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
Author
User
&lt;/pre&gt;&lt;p&gt;واجعل لكل مستخدم Role.&lt;/p&gt;&lt;p&gt;المطلوب&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة الأولى&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أضف عمود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role
&lt;/pre&gt;&lt;p&gt;إلى جدول &lt;code inline=""&gt;users&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة الثانية&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اجعل القيم الممكنة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;admin
author
user
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الثالثة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:policy ArticlePolicy --model=Article
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;المهمة الرابعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اجعل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Admin
&lt;/pre&gt;&lt;p&gt;يستطيع تعديل وحذف أي مقال.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة الخامسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اجعل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Author
&lt;/pre&gt;&lt;p&gt;يستطيع تعديل وحذف مقالاته فقط.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة السادسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اجعل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
&lt;/pre&gt;&lt;p&gt;لا يستطيع تعديل أو حذف المقالات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة السابعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$this-&amp;gt;authorize('update', $article);
&lt;/pre&gt;&lt;p&gt;داخل Controller.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة الثامنة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@can('update', $article)
&lt;/pre&gt;&lt;p&gt;لإظهار زر التعديل.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;المهمة التاسعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اختبر الحالات التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Guest
 ↓
لا يستطيع تعديل المقال

User
 ↓
لا يستطيع تعديل المقال

Author
 ↓
يستطيع تعديل مقاله

Author
 ↓
لا يستطيع تعديل مقال Author آخر

Admin
 ↓
يستطيع تعديل أي مقال
&lt;/pre&gt;&lt;p&gt;إذا تمكنت من تنفيذ هذه الحالات، فأنت بدأت بالفعل في بناء نظام Authorization عملي في Laravel.&lt;/p&gt;&lt;h3&gt;ماذا تعلمنا في هذا الدرس؟&lt;/h3&gt;&lt;p&gt;في هذا الدرس انتقلنا من Authentication إلى Authorization.&lt;/p&gt;&lt;p&gt;تعلمنا أن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
= من أنت؟

Authorization
= ماذا يسمح لك أن تفعل؟
&lt;/pre&gt;&lt;p&gt;وتعرفنا على:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Authorization.&lt;/li&gt;&lt;li&gt;Gates.&lt;/li&gt;&lt;li&gt;Policies.&lt;/li&gt;&lt;li&gt;Roles.&lt;/li&gt;&lt;li&gt;Permissions كمفهوم.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Gate::allows()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Gate::authorize()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;$user-&amp;gt;can()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;$this-&amp;gt;authorize()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;auth&lt;/code&gt; Middleware.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;can&lt;/code&gt; Middleware.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;@can&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;@cannot&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;@canany&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;Policy Methods.&lt;/li&gt;&lt;li&gt;حماية Models.&lt;/li&gt;&lt;li&gt;حماية المقالات حسب المالك.&lt;/li&gt;&lt;li&gt;السماح للـ Admin بإدارة الموارد.&lt;/li&gt;&lt;li&gt;استخدام Form Request في Authorization.&lt;/li&gt;&lt;li&gt;اختبار الصلاحيات.&lt;/li&gt;&lt;li&gt;PHP Attribute &lt;code inline=""&gt;#[Authorize]&lt;/code&gt; في Laravel 13.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;بعد أن تعلمنا Authentication في الدرس السابق، أصبح لدينا الآن الجزء الثاني من نظام المستخدمين.&lt;/p&gt;&lt;p&gt;يمكن تلخيص ما تعلمناه حتى الآن بالشكل التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
Register
 ↓
Login
 ↓
Authentication
 ↓
Session
 ↓
Authorization
 ↓
Gate / Policy
 ↓
Role / Permission
 ↓
Allowed / Denied
&lt;/pre&gt;&lt;p&gt;في تطبيق حقيقي، لا يكفي أن يعرف Laravel أن المستخدم قام بتسجيل الدخول.&lt;/p&gt;&lt;p&gt;يجب أيضًا أن يعرف ما إذا كان هذا المستخدم مخولًا لتنفيذ العملية التي يطلبها.&lt;/p&gt;&lt;p&gt;فمثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Ahmed
Role: admin
&lt;/pre&gt;&lt;p&gt;يمكنه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إدارة المستخدمين
إدارة المقالات
حذف المقالات
&lt;/pre&gt;&lt;p&gt;بينما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Mohamed
Role: author
&lt;/pre&gt;&lt;p&gt;يمكنه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إنشاء المقالات
تعديل مقالاته
حذف مقالاته
&lt;/pre&gt;&lt;p&gt;وهكذا يصبح التطبيق أكثر تنظيمًا وأمانًا.&lt;/p&gt;&lt;p&gt;وأهم قاعدة يجب أن تتذكرها هي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
→ هل المستخدم معروف ومسجل الدخول؟

Authorization
→ هل هذا المستخدم مسموح له بتنفيذ العملية؟
&lt;/pre&gt;&lt;p&gt;في الدرس القادم سننتقل إلى موضوع مهم جدًا في التطبيقات التي تعتمد على الملفات والصور، وهو &lt;strong&gt;File Storage ورفع الملفات في Laravel&lt;/strong&gt;، وسنتعلم كيفية رفع الصور والملفات وتخزينها والتحقق منها وعرضها داخل التطبيق، مع ربط ذلك بما تعلمناه عن Requests وValidation وModels.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/6445708854508793518/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-authorization-gates-policies.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6445708854508793518" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6445708854508793518" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-authorization-gates-policies.html" rel="alternate" title="الصلاحيات و الأدوار Authentication في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipSfM5sdZBaPCh3G0uqXMJ5kPhPjLVd2jGdm9ZkP5GDSTN9kXU7J59m03I0rWA2FshqE44KhHA8qGPWeUdw3NDksSBfD8dGJQsyJsrvG3SYy-RR_m_Y7wR7SUIUev-wY5sJ9-Q7ve4Qo6U3leTlKZXkJdc0_WluKxe5X1oYMCbnsIgtECeSzhuF6LaLzHB/s72-c/imageedit_1_9637435525.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-2203288963993292564</id><published>2026-09-29T11:29:28.625+03:00</published><updated>2026-09-29T11:29:28.626+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">تسجيل الدخول والتسجيل وحماية المسارات Authentication في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTT7dfRupW4jAZAQcAIe-jvQC5iWkjgs4OnQieXZRLeEYFWL-kyz_Rd5HqkY5t9SoS80L3pYzuGDlnFm0FNwTzKLpd_GPmJIDXu2DIPnD5LAm4YlE0maHhvsapM1xgLvleb-Q0EtFwa_MQ1eslFDN1zt-prKF9OGdIDGjBhJYneVTWkG80nmeQpLW1UjUW/s640/imageedit_1_3060765729.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="تسجيل الدخول والتسجيل وحماية المسارات 12" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTT7dfRupW4jAZAQcAIe-jvQC5iWkjgs4OnQieXZRLeEYFWL-kyz_Rd5HqkY5t9SoS80L3pYzuGDlnFm0FNwTzKLpd_GPmJIDXu2DIPnD5LAm4YlE0maHhvsapM1xgLvleb-Q0EtFwa_MQ1eslFDN1zt-prKF9OGdIDGjBhJYneVTWkG80nmeQpLW1UjUW/s1600/imageedit_1_3060765729.webp" title="تسجيل الدخول والتسجيل وحماية المسارات 12" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;تسجيل الدخول والتسجيل وحماية المسارات في Laravel&lt;/h3&gt;&lt;p&gt;بعد أن تعلمنا في الدروس السابقة كيفية التعامل مع قواعد البيانات و Models و Eloquent والعلاقات، ثم تعرفنا على Factories وSeeders وFaker لإنشاء البيانات التجريبية، حان الوقت للانتقال إلى جزء أساسي في معظم تطبيقات الويب: &lt;strong&gt;Authentication&lt;/strong&gt; أو نظام المصادقة.&lt;/p&gt;&lt;p&gt;إذا كنت تبني موقعًا للمقالات، متجرًا إلكترونيًا، لوحة تحكم، منصة تعليمية أو نظامًا لإدارة المستخدمين، فمن الطبيعي أن تحتاج إلى معرفة:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;من هو المستخدم الذي قام بتسجيل الدخول؟&lt;/li&gt;&lt;li&gt;كيف يمكن للمستخدم إنشاء حساب؟&lt;/li&gt;&lt;li&gt;كيف يسجل الدخول؟&lt;/li&gt;&lt;li&gt;كيف يسجل الخروج؟&lt;/li&gt;&lt;li&gt;كيف تمنع الزائر غير المسجل من الوصول إلى لوحة التحكم؟&lt;/li&gt;&lt;li&gt;كيف تسمح للمستخدم المسجل فقط بإنشاء مقال؟&lt;/li&gt;&lt;li&gt;كيف تتعامل مع كلمة المرور بطريقة آمنة؟&lt;/li&gt;&lt;li&gt;كيف تعرف المستخدم الحالي داخل Controller أو View؟&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Laravel يوفر أدوات متكاملة لهذه المهام، ويعتمد نظام المصادقة الأساسي على مفهومين مهمين هما &lt;strong&gt;Guards&lt;/strong&gt; و&lt;strong&gt;Providers&lt;/strong&gt;، كما يوفر Middleware باسم &lt;code inline=""&gt;auth&lt;/code&gt; لحماية المسارات.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنتعرف على هذه المفاهيم خطوة بخطوة، وسنربطها بما تعلمناه سابقًا.&lt;/p&gt;&lt;h3&gt;ما هو Authentication؟&lt;/h3&gt;&lt;p&gt;كلمة &lt;strong&gt;Authentication&lt;/strong&gt; تعني التحقق من هوية المستخدم.&lt;/p&gt;&lt;p&gt;بمعنى أبسط: عندما يكتب المستخدم البريد الإلكتروني وكلمة المرور، يحتاج التطبيق إلى التحقق من أن البيانات صحيحة وأن هذا المستخدم موجود بالفعل.&lt;/p&gt;&lt;p&gt;مثلًا :&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Email:
ahmed@example.com

Password:
********
&lt;/pre&gt;&lt;p&gt;يقوم Laravel بالتحقق من البيانات، وإذا كانت صحيحة يتم اعتبار المستخدم &lt;strong&gt;Authenticated&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;بعد ذلك يمكن للتطبيق معرفة أن هذا المستخدم هو المستخدم الحالي.&lt;/p&gt;&lt;p&gt;يمكن تصور العملية بالشكل التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;المستخدم
   ↓
Login Form
   ↓
Email + Password
   ↓
Laravel Authentication
   ↓
التحقق من البيانات
   ↓
إنشاء Session
   ↓
المستخدم أصبح مسجل الدخول
&lt;/pre&gt;&lt;h3&gt;Authentication و Authorization&lt;/h3&gt;&lt;p&gt;هناك مصطلحان متشابهان جدًا، لكن الفرق بينهما مهم.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Authentication&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يعني:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;من أنت؟&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;هل هذا المستخدم مسجل الدخول؟
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Authorization&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يعني:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;ماذا يسمح لك أن تفعل؟&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;مثلًا:&lt;/p&gt;&lt;pre&gt;&lt;code class="language-text"&gt;هل هذا المستخدم يستطيع حذف المقال؟
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم مسجل الدخول، فهذا Authentication.&lt;/p&gt;&lt;p&gt;أما إذا كان يستطيع حذف المقال لأنه مدير، فهذا Authorization.&lt;/p&gt;&lt;p&gt;سنركز في هذا الدرس على Authentication، وسنتوسع في Authorization والصلاحيات في درس لاحق.&lt;/p&gt;&lt;h3&gt;كيف يعمل Authentication في Laravel؟&lt;/h3&gt;&lt;p&gt;يعتمد نظام Authentication في Laravel على عدة أجزاء تعمل معًا.&lt;/p&gt;&lt;p&gt;أهمها:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;User Model&lt;/li&gt;&lt;li&gt;Authentication Guards&lt;/li&gt;&lt;li&gt;User Providers&lt;/li&gt;&lt;li&gt;Sessions&lt;/li&gt;&lt;li&gt;Middleware&lt;/li&gt;&lt;li&gt;Auth Facade&lt;/li&gt;&lt;li&gt;Starter Kits&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يشرح Laravel رسميًا أن الـ &lt;strong&gt;Guards&lt;/strong&gt; تحدد كيفية مصادقة المستخدم في كل طلب، بينما الـ &lt;strong&gt;Providers&lt;/strong&gt; تحدد كيفية استرجاع المستخدم من التخزين الدائم مثل قاعدة البيانات.&lt;/p&gt;&lt;p&gt;في تطبيقات الويب التقليدية، يستخدم Laravel عادةً Session Guard للحفاظ على حالة تسجيل الدخول باستخدام Session وCookies.&lt;/p&gt;&lt;h3&gt;User Model&lt;/h3&gt;&lt;p&gt;من الأشياء التي رأيناها منذ بداية الكورس Model المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Models/User.php
&lt;/pre&gt;&lt;p&gt;هذا الـ Model يمثل المستخدم الموجود في جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
&lt;/pre&gt;&lt;p&gt;وعادةً يحتوي جدول المستخدمين على بيانات مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
name
email
password
created_at
updated_at
&lt;/pre&gt;&lt;p&gt;يمكنك رؤية المستخدمين باستخدام Eloquent:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$users = User::all();
&lt;/pre&gt;&lt;p&gt;لكن Authentication يستخدم هذا Model أيضًا للتعرف على المستخدمين والتحقق من بياناتهم.&lt;/p&gt;&lt;h3&gt;جدول users&lt;/h3&gt;&lt;p&gt;عادةً يحتاج نظام Authentication إلى جدول للمستخدمين.&lt;/p&gt;&lt;p&gt;إذا كان المشروع الذي أنشأته يحتوي على Migration للمستخدمين، فستجد جدول &lt;code inline=""&gt;users&lt;/code&gt; بعد تشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;يمكنك التحقق من قاعدة البيانات ورؤية المستخدمين الموجودين فيها.&lt;/p&gt;&lt;p&gt;ومع استخدام Factories التي تعلمناها في الدرس السابق، يمكنك إنشاء مستخدمين تجريبيين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()-&amp;gt;count(10)-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وهذا مفيد جدًا أثناء تطوير نظام تسجيل الدخول.&lt;/p&gt;&lt;h3&gt;ما هو Starter Kit؟&lt;/h3&gt;&lt;p&gt;إذا كنت تبدأ مشروع Laravel جديدًا، فلست مضطرًا إلى بناء كل صفحات التسجيل وتسجيل الدخول يدويًا.&lt;/p&gt;&lt;p&gt;Laravel يوفر &lt;strong&gt;Starter Kits&lt;/strong&gt; رسمية تساعدك على بدء مشروع يحتوي على بنية Authentication جاهزة.&lt;/p&gt;&lt;p&gt;توضح وثائق Laravel 13 أن Starter Kits توفر المسارات والـ Controllers والواجهات اللازمة لتسجيل المستخدمين ومصادقتهم، وتستخدم Laravel Fortify لمعالجة منطق Authentication.&lt;/p&gt;&lt;p&gt;وتتوفر في Laravel 13 Starter Kits رسمية تعتمد على تقنيات مثل:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;React&lt;/li&gt;&lt;li&gt;Vue&lt;/li&gt;&lt;li&gt;Svelte&lt;/li&gt;&lt;li&gt;Livewire&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;ويمكن اختيار Starter Kit عند إنشاء تطبيق جديد باستخدام Laravel Installer.&lt;/p&gt;&lt;h3&gt;لماذا نستخدم Starter Kit؟&lt;/h3&gt;&lt;p&gt;بدل أن تبدأ من الصفر وتبني:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Register
Login
Logout
Forgot Password
Reset Password
Email Verification
2FA
&lt;/pre&gt;&lt;p&gt;يمكنك استخدام Starter Kit يوفر جزءًا كبيرًا من هذه البنية.&lt;/p&gt;&lt;p&gt;وهذا لا يعني أنك لا تحتاج إلى فهم Authentication.&lt;/p&gt;&lt;p&gt;بالعكس.&lt;/p&gt;&lt;p&gt;من المهم جدًا أن تعرف ما الذي يحدث خلف هذه الواجهات.&lt;/p&gt;&lt;p&gt;Laravel نفسه يشير إلى أن Starter Kits مفيدة ليس فقط لتسريع البداية، بل أيضًا كطريقة لدراسة كيفية تطبيق Authentication داخل مشروع حقيقي.&lt;/p&gt;&lt;h3&gt;إنشاء مشروع باستخدام Starter Kit&lt;/h3&gt;&lt;p&gt;عند إنشاء تطبيق Laravel جديد باستخدام Laravel Installer:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;laravel new my-app
&lt;/pre&gt;&lt;p&gt;يمكن للمثبت أن يطلب منك اختيار Starter Kit.&lt;/p&gt;&lt;p&gt;بعد إنشاء المشروع يمكنك تثبيت اعتماديات الواجهة وتشغيل التطبيق:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;cd my-app
npm install &amp;amp;&amp;amp; npm run build
composer run dev
&lt;/pre&gt;&lt;p&gt;ثم يمكنك فتح التطبيق في المتصفح.&lt;/p&gt;&lt;p&gt;توثيق Laravel 13 يوضح أن Starter Kits يمكن اختيارها أثناء إنشاء التطبيق، وبعد ذلك يتم تشغيل اعتماديات الواجهة والتطبيق بالطريقة المعتادة.&lt;/p&gt;&lt;h3&gt;صفحات Authentication&lt;/h3&gt;&lt;p&gt;عند استخدام Starter Kit مناسب، ستحصل على صفحات Authentication مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/register
/login
/forgot-password
/reset-password
&lt;/pre&gt;&lt;p&gt;وقد توجد أيضًا مسارات خاصة بالتحقق من البريد الإلكتروني وتسجيل الخروج وغيرها حسب الميزات المفعلة.&lt;/p&gt;&lt;p&gt;فكرة هذه الصفحات هي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/register
    ↓
إنشاء User

/login
    ↓
Authentication

/dashboard
    ↓
صفحة محمية

/logout
    ↓
إنهاء Session
&lt;/pre&gt;&lt;h3&gt;إنشاء حساب جديد&lt;/h3&gt;&lt;p&gt;عملية التسجيل تعني إنشاء User جديد في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;عادةً يحتاج النموذج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Name
Email
Password
Password Confirmation
&lt;/pre&gt;&lt;p&gt;ثم يتم التحقق من البيانات.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'name' =&amp;gt; ['required', 'string', 'max:255'],
'email' =&amp;gt; ['required', 'email', 'max:255', 'unique:users'],
'password' =&amp;gt; ['required', 'confirmed'],
&lt;/pre&gt;&lt;p&gt;لاحظ أننا استخدمنا قواعد Validation التي تعلمناها في الدرس السابع.&lt;/p&gt;&lt;p&gt;وهنا يظهر الترابط بين الدروس:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Form
 ↓
Request
 ↓
Validation
 ↓
User Model
 ↓
Database
&lt;/pre&gt;&lt;h3&gt;لماذا لا نخزن كلمة المرور كنص عادي؟&lt;/h3&gt;&lt;p&gt;هذه نقطة أمنية مهمة جدًا.&lt;/p&gt;&lt;p&gt;لا يجب تخزين كلمة المرور بهذه الطريقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;password123
&lt;/pre&gt;&lt;p&gt;داخل قاعدة البيانات.&lt;/p&gt;&lt;p&gt;بدلًا من ذلك، يجب تخزين قيمة Hash.&lt;/p&gt;&lt;p&gt;Laravel يوفر أدوات مخصصة لتشفير كلمات المرور باستخدام Hashing.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Support\Facades\Hash;

$hashedPassword = Hash::make('password123');
&lt;/pre&gt;&lt;p&gt;ثم يمكن تخزين القيمة الناتجة في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;وعند تسجيل الدخول، لا نقارن كلمة المرور النصية مباشرة بالقيمة المخزنة، بل يستخدم Laravel آلية التحقق من الـ Hash.&lt;/p&gt;&lt;p&gt;Laravel يوضح أن الخوارزمية الافتراضية لكلمات المرور هي bcrypt، كما يدعم إعادة Hashing تلقائيًا عند الحاجة أثناء تسجيل الدخول.&lt;/p&gt;&lt;h3&gt;تسجيل الدخول Login&lt;/h3&gt;&lt;p&gt;تسجيل الدخول يعني إرسال بيانات المستخدم إلى Laravel للتحقق منها.&lt;/p&gt;&lt;p&gt;يمكن تنفيذ Authentication يدويًا باستخدام &lt;code inline=""&gt;Auth&lt;/code&gt; Facade.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Support\Facades\Auth;

if (Auth::attempt([
    'email' =&amp;gt; $request-&amp;gt;email,
    'password' =&amp;gt; $request-&amp;gt;password,
])) {
    // Login successful
}
&lt;/pre&gt;&lt;p&gt;إذا كانت البيانات صحيحة، يتم تسجيل المستخدم.&lt;/p&gt;&lt;p&gt;أما إذا كانت غير صحيحة، يمكنك إعادة المستخدم إلى صفحة تسجيل الدخول مع رسالة خطأ.&lt;/p&gt;&lt;h3&gt;لماذا نستخدم Auth::attempt()؟&lt;/h3&gt;&lt;p&gt;الدالة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::attempt()
&lt;/pre&gt;&lt;p&gt;مخصصة لمحاولة تسجيل الدخول باستخدام بيانات الاعتماد التي تقدمها.&lt;/p&gt;&lt;p&gt;يمكن أن تحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;[
    'email' =&amp;gt; $request-&amp;gt;email,
    'password' =&amp;gt; $request-&amp;gt;password,
]
&lt;/pre&gt;&lt;p&gt;Laravel يبحث عن المستخدم بناءً على البيانات المناسبة ويتحقق من كلمة المرور.&lt;/p&gt;&lt;p&gt;إذا نجحت العملية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::attempt(...)
&lt;/pre&gt;&lt;p&gt;تعيد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;true
&lt;/pre&gt;&lt;p&gt;وإذا فشلت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;false
&lt;/pre&gt;&lt;p&gt;توثيق Laravel يوضح أن &lt;code inline=""&gt;attempt()&lt;/code&gt; تستخدم عادةً لمعالجة بيانات نموذج تسجيل الدخول، ويوصي بإعادة توليد Session بعد نجاح المصادقة للحماية من Session Fixation.&lt;/p&gt;&lt;h3&gt;إعادة توليد Session بعد تسجيل الدخول&lt;/h3&gt;&lt;p&gt;بعد نجاح تسجيل الدخول، من الممارسات المهمة إعادة توليد Session:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;session()-&amp;gt;regenerate();
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (Auth::attempt([
    'email' =&amp;gt; $request-&amp;gt;email,
    'password' =&amp;gt; $request-&amp;gt;password,
])) {
    $request-&amp;gt;session()-&amp;gt;regenerate();

    return redirect()-&amp;gt;intended('/dashboard');
}
&lt;/pre&gt;&lt;p&gt;الفكرة هنا أن Laravel يحافظ على Session آمنة بعد نجاح تسجيل الدخول.&lt;/p&gt;&lt;h3&gt;ما معنى redirect()-&amp;gt;intended()؟&lt;/h3&gt;&lt;p&gt;عندما يحاول مستخدم غير مسجل الدخول الوصول إلى صفحة محمية، يمكن أن يعيد Laravel المستخدم إلى صفحة تسجيل الدخول.&lt;/p&gt;&lt;p&gt;بعد نجاح تسجيل الدخول، يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;redirect()-&amp;gt;intended('/dashboard')
&lt;/pre&gt;&lt;p&gt;بحيث يتم توجيه المستخدم إلى الصفحة التي كان يريد الوصول إليها، وإذا لم توجد صفحة سابقة محددة يتم استخدام &lt;code inline=""&gt;/dashboard&lt;/code&gt; كوجهة افتراضية.&lt;/p&gt;&lt;p&gt;وهذه تجربة أفضل للمستخدم من إرساله دائمًا إلى نفس الصفحة.&lt;/p&gt;&lt;h3&gt;كيف نعرف أن المستخدم مسجل الدخول؟&lt;/h3&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::check()
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Support\Facades\Auth;

if (Auth::check()) {
    // المستخدم مسجل الدخول
}
&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم مسجلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;true
&lt;/pre&gt;&lt;p&gt;وإذا لم يكن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;false
&lt;/pre&gt;&lt;p&gt;Laravel يوثق &lt;code inline=""&gt;Auth::check()&lt;/code&gt; كطريقة للتحقق مما إذا كان المستخدم الحالي مصادقًا عليه.&lt;/p&gt;&lt;h3&gt;الحصول على المستخدم الحالي&lt;/h3&gt;&lt;p&gt;إذا أردت الحصول على بيانات المستخدم الذي قام بتسجيل الدخول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = Auth::user();
&lt;/pre&gt;&lt;p&gt;ثم يمكنك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;echo $user-&amp;gt;name;
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;echo $user-&amp;gt;email;
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (Auth::check()) {
    $user = Auth::user();

    return $user-&amp;gt;name;
}
&lt;/pre&gt;&lt;h3&gt;استخدام auth() Helper&lt;/h3&gt;&lt;p&gt;يمكنك أيضًا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;auth()-&amp;gt;user()
&lt;/pre&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::user()
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = auth()-&amp;gt;user();
&lt;/pre&gt;&lt;p&gt;والتحقق:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (auth()-&amp;gt;check()) {
    // User is authenticated
}
&lt;/pre&gt;&lt;p&gt;هذه الطريقة شائعة جدًا في Laravel.&lt;/p&gt;&lt;h3&gt;حماية Routes باستخدام auth Middleware&lt;/h3&gt;&lt;p&gt;تخيل أن لديك صفحة Dashboard:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/dashboard', function () {
    return view('dashboard');
});
&lt;/pre&gt;&lt;p&gt;في هذه الحالة يمكن لأي شخص الوصول إليها.&lt;/p&gt;&lt;p&gt;إذا أردت السماح للمستخدمين المسجلين فقط، يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/dashboard', function () {
    return view('dashboard');
})-&amp;gt;middleware('auth');
&lt;/pre&gt;&lt;p&gt;الآن أصبح Route محميًا.&lt;/p&gt;&lt;p&gt;Laravel يوفر Middleware باسم &lt;code inline=""&gt;auth&lt;/code&gt; للتحقق من أن المستخدم مسجل الدخول قبل السماح له بالوصول إلى المسار.&lt;/p&gt;&lt;h3&gt;حماية مجموعة من Routes&lt;/h3&gt;&lt;p&gt;إذا كان لديك أكثر من صفحة تحتاج إلى تسجيل الدخول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/dashboard
/profile
/settings
/articles/create
/articles/edit
&lt;/pre&gt;&lt;p&gt;يمكنك استخدام Route Group:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::middleware('auth')-&amp;gt;group(function () {

    Route::get('/dashboard', function () {
        return view('dashboard');
    });

    Route::get('/profile', function () {
        return view('profile');
    });

    Route::get('/settings', function () {
        return view('settings');
    });

});
&lt;/pre&gt;&lt;p&gt;بهذه الطريقة يتم تطبيق &lt;code inline=""&gt;auth&lt;/code&gt; Middleware على جميع Routes داخل المجموعة.&lt;/p&gt;&lt;h3&gt;Authentication مع Controllers&lt;/h3&gt;&lt;p&gt;في التطبيقات الحقيقية غالبًا لن تضع منطق التطبيق كله داخل Route Closure.&lt;/p&gt;&lt;p&gt;يمكنك استخدام Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/dashboard', [DashboardController::class, 'index'])
    -&amp;gt;middleware('auth');
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;class DashboardController extends Controller
{
    public function index()
    {
        $user = auth()-&amp;gt;user();

        return view('dashboard', compact('user'));
    }
}
&lt;/pre&gt;&lt;p&gt;وهنا نستخدم المفاهيم التي تعلمناها في الدرس الخامس:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route
 ↓
Controller
 ↓
Auth
 ↓
View
&lt;/pre&gt;&lt;h3&gt;عرض اسم المستخدم في Blade&lt;/h3&gt;&lt;p&gt;بعد إرسال المستخدم إلى View:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return view('dashboard', compact('user'));
&lt;/pre&gt;&lt;p&gt;يمكننا في Blade كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;h1&amp;gt;مرحبًا {{ $user-&amp;gt;name }}&amp;lt;/h1&amp;gt;
&lt;/pre&gt;&lt;p&gt;ويمكننا أيضًا استخدام Auth مباشرة في Blade حسب الحاجة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@if (auth()-&amp;gt;check())
    &amp;lt;p&amp;gt;مرحبًا {{ auth()-&amp;gt;user()-&amp;gt;name }}&amp;lt;/p&amp;gt;
@endif
&lt;/pre&gt;&lt;h3&gt;عرض محتوى مختلف للمستخدم والزائر&lt;/h3&gt;&lt;p&gt;يمكنك إنشاء واجهة تختلف حسب حالة Authentication:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@if (auth()-&amp;gt;check())
    &amp;lt;p&amp;gt;مرحبًا {{ auth()-&amp;gt;user()-&amp;gt;name }}&amp;lt;/p&amp;gt;

    &amp;lt;a href="/dashboard"&amp;gt;لوحة التحكم&amp;lt;/a&amp;gt;
@else
    &amp;lt;a href="/login"&amp;gt;تسجيل الدخول&amp;lt;/a&amp;gt;
    &amp;lt;a href="/register"&amp;gt;إنشاء حساب&amp;lt;/a&amp;gt;
@endif
&lt;/pre&gt;&lt;p&gt;وهنا نستخدم ما تعلمناه في الدرس السادس عن Blade وViews.&lt;/p&gt;&lt;h3&gt;تسجيل الخروج Logout&lt;/h3&gt;&lt;p&gt;عندما يريد المستخدم إنهاء الجلسة، يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::logout();
&lt;/pre&gt;&lt;p&gt;لكن من الأفضل أيضًا إبطال Session وتجديد CSRF Token:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::logout();

$request-&amp;gt;session()-&amp;gt;invalidate();

$request-&amp;gt;session()-&amp;gt;regenerateToken();

return redirect('/');
&lt;/pre&gt;&lt;p&gt;وبذلك تنتهي جلسة المستخدم الحالية.&lt;/p&gt;&lt;p&gt;Laravel يوفر توثيقًا مباشرًا لعملية تسجيل الخروج وإبطال الجلسة.&lt;/p&gt;&lt;h3&gt;لماذا لا نستخدم GET لتسجيل الخروج؟&lt;/h3&gt;&lt;p&gt;من الأفضل أن تكون العمليات التي تغير حالة التطبيق مبنية على HTTP method مناسب.&lt;/p&gt;&lt;p&gt;لذلك عادةً يكون Logout عبر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;POST /logout
&lt;/pre&gt;&lt;p&gt;وليس رابطًا عاديًا من نوع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;GET /logout
&lt;/pre&gt;&lt;p&gt;وهذا يتناسب مع طريقة عمل Starter Kits الرسمية، حيث يوفر Fortify مسار Logout باستخدام &lt;code inline=""&gt;POST&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;نموذج Logout في Blade&lt;/h3&gt;&lt;p&gt;إذا كان Route الخاص بالخروج يتطلب POST، يمكن استخدام Form:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST" action="/logout"&amp;gt;
    @csrf

    &amp;lt;button type="submit"&amp;gt;
        تسجيل الخروج
    &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;p&gt;لاحظ وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@csrf
&lt;/pre&gt;&lt;p&gt;وهذا المفهوم تعلمناه في درس Requests وValidation.&lt;/p&gt;&lt;p&gt;مرة أخرى نرى كيف ترتبط دروس Laravel ببعضها.&lt;/p&gt;&lt;h3&gt;Authentication وCSRF&lt;/h3&gt;&lt;p&gt;عند إنشاء Form يستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;POST
PUT
PATCH
DELETE
&lt;/pre&gt;&lt;p&gt;يجب الانتباه إلى CSRF Protection في تطبيقات الويب.&lt;/p&gt;&lt;p&gt;لذلك نستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@csrf
&lt;/pre&gt;&lt;p&gt;داخل النموذج.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST" action="/login"&amp;gt;
    @csrf

    &amp;lt;input type="email" name="email"&amp;gt;

    &amp;lt;input type="password" name="password"&amp;gt;

    &amp;lt;button type="submit"&amp;gt;
        تسجيل الدخول
    &amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;h3&gt;Login Controller يدوي بسيط&lt;/h3&gt;&lt;p&gt;إذا أردت فهم ما يحدث خلف Starter Kit، يمكننا تصور Controller بسيط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    public function login(Request $request)
    {
        $credentials = $request-&amp;gt;validate([
            'email' =&amp;gt; ['required', 'email'],
            'password' =&amp;gt; ['required'],
        ]);

        if (Auth::attempt($credentials)) {
            $request-&amp;gt;session()-&amp;gt;regenerate();

            return redirect()-&amp;gt;intended('/dashboard');
        }

        return back()-&amp;gt;withErrors([
            'email' =&amp;gt; 'بيانات تسجيل الدخول غير صحيحة.',
        ])-&amp;gt;onlyInput('email');
    }
}
&lt;/pre&gt;&lt;p&gt;لاحظ أننا جمعنا عدة مفاهيم تعلمناها في الدروس السابقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Request
 ↓
Validation
 ↓
Auth::attempt()
 ↓
Session
 ↓
Redirect
&lt;/pre&gt;&lt;h3&gt;Login Route&lt;/h3&gt;&lt;p&gt;يمكن أن يكون لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::post('/login', [LoginController::class, 'login'])
    -&amp;gt;name('login');
&lt;/pre&gt;&lt;p&gt;أما صفحة تسجيل الدخول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/login', function () {
    return view('auth.login');
})-&amp;gt;middleware('guest');
&lt;/pre&gt;&lt;h3&gt;ما هو guest Middleware؟&lt;/h3&gt;&lt;p&gt;كما يوجد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;auth
&lt;/pre&gt;&lt;p&gt;لحماية الصفحات من الزوار، يوجد أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;guest
&lt;/pre&gt;&lt;p&gt;ويُستخدم عادةً للصفحات التي يفترض أن يصل إليها الزائر غير المسجل فقط.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/login', function () {
    return view('auth.login');
})-&amp;gt;middleware('guest');
&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم مسجل الدخول بالفعل، فلا حاجة لإظهار صفحة Login له.&lt;/p&gt;&lt;h3&gt;الفرق بين auth وguest&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;يمكن تبسيط الأمر:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;auth
 ↓
السماح للمستخدم المسجل فقط
&lt;/pre&gt;&lt;p&gt;بينما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;guest
 ↓
السماح للزائر غير المسجل
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/dashboard → auth
/login     → guest
/register  → guest
&lt;/pre&gt;&lt;h3&gt;Login Throttling&lt;/h3&gt;&lt;p&gt;من المشاكل الأمنية التي يجب الانتباه إليها محاولات تسجيل الدخول المتكررة.&lt;/p&gt;&lt;p&gt;تخيل شخصًا يحاول آلاف كلمات المرور على نفس الحساب.&lt;/p&gt;&lt;p&gt;هذه العملية تسمى عادةً &lt;strong&gt;Brute Force Attack&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Laravel Starter Kits توفر Rate Limiting لمحاولات تسجيل الدخول، ويمكن تخصيص آلية تحديد معدل المحاولات. وتوضح وثائق Laravel 13 أن Starter Kits تطبق throttling لمحاولات تسجيل الدخول، مع إمكانية تخصيص Rate Limiting.&lt;/p&gt;&lt;p&gt;وهذا يوضح أهمية عدم بناء نظام Login بطريقة عشوائية دون الاهتمام بالحماية.&lt;/p&gt;&lt;h3&gt;Email Verification&lt;/h3&gt;&lt;p&gt;في بعض التطبيقات لا يكفي أن ينشئ المستخدم حسابًا.&lt;/p&gt;&lt;p&gt;قد ترغب في التأكد من أن البريد الإلكتروني الذي أدخله المستخدم يخصه فعلًا.&lt;/p&gt;&lt;p&gt;هنا يأتي مفهوم:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Email Verification&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أي إرسال رسالة إلى البريد الإلكتروني تحتوي على رابط لتأكيد البريد.&lt;/p&gt;&lt;p&gt;Starter Kits الرسمية تدعم Email Verification ضمن ميزات Authentication.&lt;/p&gt;&lt;h3&gt;Password Reset&lt;/h3&gt;&lt;p&gt;ماذا يحدث إذا نسي المستخدم كلمة المرور؟&lt;/p&gt;&lt;p&gt;لا يجب أن تطلب منه إرسال كلمة المرور القديمة.&lt;/p&gt;&lt;p&gt;بدلًا من ذلك، يوفر Laravel آلية لإعادة تعيين كلمة المرور.&lt;/p&gt;&lt;p&gt;عادةً تبدأ العملية من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Forgot Password
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Email
 ↓
Reset Link
 ↓
New Password
&lt;/pre&gt;&lt;p&gt;Starter Kits توفر صفحات ومسارات خاصة باستعادة وإعادة تعيين كلمة المرور.&lt;/p&gt;&lt;h3&gt;Two-Factor Authentication&lt;/h3&gt;&lt;p&gt;في التطبيقات التي تحتاج مستوى أعلى من الأمان، يمكن استخدام &lt;strong&gt;Two-Factor Authentication – 2FA&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;الفكرة أن كلمة المرور وحدها لا تكفي.&lt;/p&gt;&lt;p&gt;بعد إدخال كلمة المرور، يحتاج المستخدم إلى رمز إضافي يتم توليده بواسطة تطبيق Authenticator متوافق.&lt;/p&gt;&lt;p&gt;Starter Kits الحديثة في Laravel توفر دعمًا لـ 2FA ويمكن تفعيلها حسب إعدادات التطبيق.&lt;/p&gt;&lt;h3&gt;أين توجد إعدادات Authentication؟&lt;/h3&gt;&lt;p&gt;من الملفات المهمة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;config/auth.php
&lt;/pre&gt;&lt;p&gt;يحتوي هذا الملف على إعدادات Guards وProviders وغيرها من إعدادات Authentication.&lt;/p&gt;&lt;p&gt;لكن كمبتدئ، لا تحتاج إلى تغيير كل شيء فيه.&lt;/p&gt;&lt;p&gt;من الأفضل أولًا فهم النظام الافتراضي، ثم تعديل الإعدادات عندما تحتاج إلى ذلك.&lt;/p&gt;&lt;p&gt;Laravel يوضح أن &lt;code inline=""&gt;config/auth.php&lt;/code&gt; هو ملف إعداد Authentication الرئيسي للتطبيق.&lt;/p&gt;&lt;h3&gt;دورة تسجيل الدخول كاملة&lt;/h3&gt;&lt;p&gt;لنلخص العملية التي تحدث عندما يسجل المستخدم الدخول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;المستخدم
   ↓
يفتح /login
   ↓
Login Form
   ↓
يدخل Email + Password
   ↓
POST /login
   ↓
Validation
   ↓
Auth::attempt()
   ↓
التحقق من User
   ↓
التحقق من Password Hash
   ↓
Session
   ↓
المستخدم أصبح Authenticated
   ↓
redirect('/dashboard')
&lt;/pre&gt;&lt;p&gt;وبعد ذلك عندما يزور المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/dashboard
&lt;/pre&gt;&lt;p&gt;يعمل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;auth Middleware
&lt;/pre&gt;&lt;p&gt;ويتحقق من أن المستخدم مصادق عليه.&lt;/p&gt;&lt;p&gt;إذا كان مسجلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Allow
&lt;/pre&gt;&lt;p&gt;وإذا لم يكن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Redirect to Login
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;مثال عملي كامل&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنفترض أننا نريد بناء منطقة خاصة للمستخدمين.&lt;/p&gt;&lt;p&gt;لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/login
/register
/dashboard
/profile
/logout
&lt;/pre&gt;&lt;p&gt;يمكن تصور Routes بالشكل التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::middleware('guest')-&amp;gt;group(function () {
    Route::get('/login', [LoginController::class, 'show'])
        -&amp;gt;name('login');

    Route::post('/login', [LoginController::class, 'login']);

    Route::get('/register', [RegisterController::class, 'show'])
        -&amp;gt;name('register');

    Route::post('/register', [RegisterController::class, 'register']);
});

Route::middleware('auth')-&amp;gt;group(function () {
    Route::get('/dashboard', [DashboardController::class, 'index'])
        -&amp;gt;name('dashboard');

    Route::get('/profile', [ProfileController::class, 'index'])
        -&amp;gt;name('profile');

    Route::post('/logout', [LoginController::class, 'logout'])
        -&amp;gt;name('logout');
});
&lt;/pre&gt;&lt;p&gt;الفكرة الأساسية هنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Guest
 ↓
Login / Register

Authenticated User
 ↓
Dashboard / Profile / Logout
&lt;/pre&gt;&lt;h3&gt;ربط Authentication بالدرس السابق&lt;/h3&gt;&lt;p&gt;في الدرس الحادي عشر تعلمنا Factories وSeeders.&lt;/p&gt;&lt;p&gt;يمكننا الآن استخدامها لإنشاء مستخدم تجريبي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()-&amp;gt;create([
    'name' =&amp;gt; 'Ahmed',
    'email' =&amp;gt; 'ahmed@example.com',
]);
&lt;/pre&gt;&lt;p&gt;وبذلك نستطيع استخدام هذا المستخدم أثناء اختبار Authentication.&lt;/p&gt;&lt;p&gt;وهكذا أصبح لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Factory
 ↓
User
 ↓
Database
 ↓
Login
 ↓
Authentication
&lt;/pre&gt;&lt;h3&gt;أخطاء شائعة&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;وضع كلمة المرور كنص عادي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;خطأ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'password' =&amp;gt; '123456'
&lt;/pre&gt;&lt;p&gt;عند إنشاء مستخدم بشكل يدوي دون Hash.&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'password' =&amp;gt; Hash::make('123456')
&lt;/pre&gt;&lt;p&gt;أو اعتمد على الآلية التي يوفرها Starter Kit لإنشاء المستخدمين.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;نسيان auth Middleware&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كان لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/dashboard', ...);
&lt;/pre&gt;&lt;p&gt;فهذا لا يعني تلقائيًا أن الصفحة محمية.&lt;/p&gt;&lt;p&gt;يجب حماية المسار:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/dashboard', ...)
    -&amp;gt;middleware('auth');
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;نسيان regenerate بعد Login&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;بعد نجاح:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::attempt()
&lt;/pre&gt;&lt;p&gt;يجب التعامل مع Session بالشكل الصحيح، ومن الممارسات التي توثقها Laravel إعادة توليد Session بعد نجاح تسجيل الدخول.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;استخدام GET لتسجيل الخروج&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لا تجعل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;GET /logout
&lt;/pre&gt;&lt;p&gt;هو الوسيلة الأساسية لتسجيل الخروج.&lt;/p&gt;&lt;p&gt;استخدم POST مع CSRF Protection.&lt;/p&gt;&lt;h3&gt;الخلط بين Authentication وAuthorization&lt;/h3&gt;&lt;p&gt;تذكر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
= من أنت؟
&lt;/pre&gt;&lt;p&gt;بينما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authorization
= ماذا يسمح لك أن تفعل؟
&lt;/pre&gt;&lt;p&gt;وهما مفهومان مختلفان.&lt;/p&gt;&lt;h3&gt;أفضل الممارسات&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;استخدم Starter Kits عندما تناسب مشروعك&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كنت تبدأ مشروعًا جديدًا وتحتاج إلى Authentication كامل، فإن Starter Kits الرسمية يمكن أن توفر لك أساسًا جاهزًا وقابلًا للتخصيص.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لا تخزن كلمات المرور كنص عادي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم Hashing المناسب.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;احمِ المسارات الحساسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;-&amp;gt;middleware('auth')
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;استخدم Validation&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لا تقبل بيانات Login أو Registration دون التحقق منها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;اهتم بالـ Rate Limiting&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;خصوصًا في عمليات تسجيل الدخول.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;افصل Authentication عن Authorization&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;تسجيل الدخول ليس هو نفسه نظام الصلاحيات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تمرين عملي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;الآن جاء دورك.&lt;/p&gt;&lt;p&gt;أنشئ تطبيقًا بسيطًا يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Register
Login
Dashboard
Profile
Logout
&lt;/pre&gt;&lt;p&gt;ثم حاول تنفيذ الآتي:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الأولى&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ مستخدمًا تجريبيًا باستخدام Factory.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثانية&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ صفحة Login.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثالثة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أضف Form يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Email
Password
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;الخطوة الرابعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم Validation:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    'email' =&amp;gt; ['required', 'email'],
    'password' =&amp;gt; ['required'],
]);
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;الخطوة الخامسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Auth::attempt()
&lt;/pre&gt;&lt;p&gt;للتحقق من بيانات المستخدم.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة السادسة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;بعد نجاح تسجيل الدخول استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;session()-&amp;gt;regenerate();
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;الخطوة السابعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ Dashboard محمية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/dashboard', ...)
    -&amp;gt;middleware('auth');
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;الخطوة الثامنة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اعرض اسم المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;{{ auth()-&amp;gt;user()-&amp;gt;name }}
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;الخطوة التاسعة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أنشئ Logout باستخدام POST.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;الخطوة العاشرة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;اختبر السيناريو التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;زائر
 ↓
يحاول فتح Dashboard
 ↓
يذهب إلى Login
 ↓
يسجل الدخول
 ↓
يعود إلى Dashboard
 ↓
يشاهد اسمه
 ↓
يضغط Logout
 ↓
يصبح Guest
&lt;/pre&gt;&lt;p&gt;إذا استطعت تنفيذ هذا السيناريو، فقد فهمت الأساس الحقيقي لنظام Authentication في Laravel.&lt;/p&gt;&lt;h3&gt;ماذا تعلمنا في هذا الدرس؟&lt;/h3&gt;&lt;p&gt;في هذا الدرس تعرفنا على مفهوم Authentication وكيف يستخدم Laravel للتحقق من هوية المستخدم.&lt;/p&gt;&lt;p&gt;تعلمنا الفرق بين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authentication
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Authorization
&lt;/pre&gt;&lt;p&gt;وتعرفنا على:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;User Model.&lt;/li&gt;&lt;li&gt;Guards.&lt;/li&gt;&lt;li&gt;Providers.&lt;/li&gt;&lt;li&gt;Sessions.&lt;/li&gt;&lt;li&gt;Auth Facade.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Auth::check()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Auth::user()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;Auth::attempt()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;auth()-&amp;gt;user()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;auth&lt;/code&gt; Middleware.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;guest&lt;/code&gt; Middleware.&lt;/li&gt;&lt;li&gt;تسجيل الدخول.&lt;/li&gt;&lt;li&gt;تسجيل الخروج.&lt;/li&gt;&lt;li&gt;Session Regeneration.&lt;/li&gt;&lt;li&gt;Password Hashing.&lt;/li&gt;&lt;li&gt;Email Verification.&lt;/li&gt;&lt;li&gt;Password Reset.&lt;/li&gt;&lt;li&gt;Login Throttling.&lt;/li&gt;&lt;li&gt;Starter Kits.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;كما رأينا كيف تتصل هذه المفاهيم بما تعلمناه سابقًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Blade
 ↓
Form
 ↓
Request
 ↓
Validation
 ↓
Auth
 ↓
Session
 ↓
Middleware
 ↓
Controller
 ↓
User Model
 ↓
Database
&lt;/pre&gt;&lt;p&gt;وهذه السلسلة تمثل جزءًا أساسيًا جدًا من تطبيقات Laravel الحديثة.&lt;/p&gt;&lt;p&gt;Authentication هو أحد أهم الأجزاء في أي تطبيق يحتوي على مستخدمين.&lt;/p&gt;&lt;p&gt;لم يعد المستخدم بالنسبة لنا مجرد سجل موجود داخل جدول &lt;code inline=""&gt;users&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;أصبح لدينا الآن مفهوم كامل لإدارة المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Register
   ↓
User
   ↓
Login
   ↓
Authentication
   ↓
Session
   ↓
Protected Routes
   ↓
Dashboard
   ↓
Logout
&lt;/pre&gt;&lt;p&gt;وتعلمنا أن Laravel يوفر أدوات جاهزة للتعامل مع هذه العمليات، كما يوفر Starter Kits رسمية تساعد على بناء طبقة Authentication متكاملة بدل كتابة كل شيء من الصفر.&lt;/p&gt;&lt;p&gt;في الدرس القادم سننتقل إلى خطوة مهمة جدًا بعد Authentication، وهي &lt;strong&gt;Authorization والصلاحيات والأدوار Roles &amp;amp; Permissions&lt;/strong&gt;، لنتعلم كيف نفرق بين المستخدم العادي والمدير، وكيف نسمح لكل مستخدم بتنفيذ العمليات المناسبة له فقط.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/2203288963993292564/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-authentication.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/2203288963993292564" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/2203288963993292564" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-authentication.html" rel="alternate" title="تسجيل الدخول والتسجيل وحماية المسارات Authentication في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTT7dfRupW4jAZAQcAIe-jvQC5iWkjgs4OnQieXZRLeEYFWL-kyz_Rd5HqkY5t9SoS80L3pYzuGDlnFm0FNwTzKLpd_GPmJIDXu2DIPnD5LAm4YlE0maHhvsapM1xgLvleb-Q0EtFwa_MQ1eslFDN1zt-prKF9OGdIDGjBhJYneVTWkG80nmeQpLW1UjUW/s72-c/imageedit_1_3060765729.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-9154505850998750500</id><published>2026-09-28T10:50:45.912+03:00</published><updated>2026-09-28T10:50:45.913+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">إنشاء بيانات تجريبية بسهولة Factories في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNNqWbLSmHm6i1IgdSf9K2vj0FngDX-_GC0qf8gXZ5hlNfzOKXKxGiBX029ScgusQm6w6FOsAR6XIHbGgxiI0A3K9tra1uvnYNeqVtnQUklc9XJ3-GsyF4Cmo8cjmwdJquzvsbE-wlXCc_dEPqWqc5QOH2PukSpBh1QVtlrKhQeSfSqhQ7YWIVb5_f2G5Y/s640/imageedit_1_8808712567.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="التعامل مع قواعد البيانات في Laravel 11" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNNqWbLSmHm6i1IgdSf9K2vj0FngDX-_GC0qf8gXZ5hlNfzOKXKxGiBX029ScgusQm6w6FOsAR6XIHbGgxiI0A3K9tra1uvnYNeqVtnQUklc9XJ3-GsyF4Cmo8cjmwdJquzvsbE-wlXCc_dEPqWqc5QOH2PukSpBh1QVtlrKhQeSfSqhQ7YWIVb5_f2G5Y/s1600/imageedit_1_8808712567.webp" title="التعامل مع قواعد البيانات في Laravel 11" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;إنشاء بيانات تجريبية بسهولة Factories و Seeders و Faker في Laravel&lt;/h3&gt;&lt;p&gt;بعد أن تعلّمنا في الدروس السابقة كيفية إنشاء قواعد البيانات والجداول باستخدام &lt;a href="https://www.nusurtech.ca/2026/09/laravel-database-migrations.html" target="_blank"&gt;Migrations&lt;/a&gt;، وكيفية التعامل مع البيانات باستخدام Models وEloquent، ثم تعلّمنا كيفية إنشاء العلاقات بين الجداول، نصل الآن إلى موضوع مهم جدًا في تطوير تطبيقات &lt;a href="https://www.nusurtech.ca/2026/09/what-is-laravel.html" target="_blank"&gt;Laravel&lt;/a&gt;: &lt;strong&gt;إنشاء البيانات التجريبية واختبار التطبيق ببيانات واقعية&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;تخيل أنك أنشأت تطبيق مدونة يحتوي على عشرات المقالات والمستخدمين والتعليقات والتصنيفات. هل ستقوم بإضافة كل سجل يدويًا من خلال لوحة الإدارة؟ بالتأكيد لا.&lt;/p&gt;&lt;p&gt;هنا تأتي أهمية ثلاثة مفاهيم أساسية في Laravel:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;&lt;strong&gt;Factories&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Seeders&lt;/strong&gt;&lt;/li&gt;&lt;li&gt;&lt;strong&gt;Faker&lt;/strong&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;تسمح لك هذه الأدوات بإنشاء مئات أو آلاف السجلات بسرعة، وربطها ببعضها، وتجهيز قاعدة البيانات أثناء مرحلة التطوير والاختبار.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنبني مثالًا عمليًا على نظام مقالات يحتوي على Users وArticles، وسنتعلم كيف ننشئ بيانات وهمية ومنظمة يمكن استخدامها أثناء تطوير التطبيق.&lt;/p&gt;&lt;h3&gt;ما هي Factories في Laravel؟&lt;/h3&gt;&lt;p&gt;الـ &lt;strong&gt;Factory&lt;/strong&gt; هي طريقة لتعريف مجموعة من البيانات الافتراضية التي يمكن استخدامها لإنشاء سجلات جديدة من Model معين.&lt;/p&gt;&lt;p&gt;بدلًا من كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create([
    'title' =&amp;gt; 'Laravel Tutorial',
    'slug' =&amp;gt; 'laravel-tutorial',
    'content' =&amp;gt; 'Learn Laravel step by step...',
]);
&lt;/pre&gt;&lt;p&gt;ثم تكرار العملية عشرات المرات، يمكننا إنشاء Factory تحدد شكل البيانات، وبعد ذلك نطلب من Laravel إنشاء العدد الذي نريده.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;count(20)-&amp;gt;create();
&lt;/pre&gt;
&lt;p&gt;السطر السابق يمكنه إنشاء 20 مقالًا باستخدام البيانات التي عرّفناها في Factory.&lt;/p&gt;&lt;p&gt;توثيق Laravel الرسمي يوضح أن Factories تعتمد على تعريف &lt;code inline=""&gt;definition()&lt;/code&gt; لإرجاع القيم الافتراضية، ويمكنها استخدام Faker لإنشاء بيانات عشوائية مناسبة.&lt;/p&gt;&lt;h3&gt;ما هو Faker؟&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Faker&lt;/strong&gt; هو مكتبة تستخدم لإنشاء بيانات وهمية تشبه البيانات الحقيقية.&lt;/p&gt;&lt;p&gt;يمكن استخدامها لإنشاء:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;أسماء.&lt;/li&gt;&lt;li&gt;بريد إلكتروني.&lt;/li&gt;&lt;li&gt;عناوين.&lt;/li&gt;&lt;li&gt;جمل.&lt;/li&gt;&lt;li&gt;نصوص.&lt;/li&gt;&lt;li&gt;أرقام.&lt;/li&gt;&lt;li&gt;تواريخ.&lt;/li&gt;&lt;li&gt;عناوين URL.&lt;/li&gt;&lt;li&gt;بيانات أخرى كثيرة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;fake()-&amp;gt;name()
&lt;/pre&gt;&lt;p&gt;يمكن أن يعيد اسمًا عشوائيًا.&lt;/p&gt;&lt;p&gt;وهذا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;fake()-&amp;gt;email()
&lt;/pre&gt;&lt;p&gt;يمكن أن يعيد بريدًا إلكترونيًا وهميًا.&lt;/p&gt;&lt;p&gt;وهذا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;fake()-&amp;gt;sentence()
&lt;/pre&gt;&lt;p&gt;ينشئ جملة عشوائية.&lt;/p&gt;&lt;p&gt;وهذا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;fake()-&amp;gt;paragraph()
&lt;/pre&gt;&lt;p&gt;ينشئ فقرة نصية.&lt;/p&gt;&lt;p&gt;ميزة Faker أنك لا تحتاج إلى كتابة بيانات مختلفة لكل سجل بنفسك.&lt;/p&gt;&lt;h3&gt;لماذا نحتاج إلى Factories وFaker؟&lt;/h3&gt;&lt;h3&gt;هناك عدة أسباب تجعل هذه الأدوات مهمة جدًا أثناء تطوير Laravel.&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;اختبار تصميم الواجهة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;عندما تبني صفحة تعرض المقالات، من المفيد أن ترى كيف ستبدو الصفحة عندما تحتوي على 10 أو 50 أو 100 مقال.&lt;/p&gt;&lt;p&gt;بدلًا من إدخال هذه البيانات يدويًا، يمكنك إنشاءها باستخدام Factory.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;اختبار Pagination&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كانت الصفحة تعرض 10 مقالات في كل صفحة، فمن الصعب اختبار Pagination بوجود مقالين فقط.&lt;/p&gt;&lt;p&gt;يمكنك إنشاء 100 مقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;count(100)-&amp;gt;create();
&lt;/pre&gt;
&lt;p&gt;وبذلك يمكنك اختبار الصفحات المختلفة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;اختبار البحث&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;وجود بيانات كثيرة يسمح لك باختبار البحث والتصفية والترتيب.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;اختبار العلاقات&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كان لديك User لديه Articles، وArticle لديه Comments، يمكنك إنشاء هذه البيانات والعلاقات تلقائيًا.&lt;/p&gt;&lt;h3&gt;تطوير لوحة الإدارة&lt;/h3&gt;&lt;p&gt;لوحة الإدارة تحتاج عادةً إلى كمية كبيرة من البيانات حتى تستطيع اختبار:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;الجداول.&lt;/li&gt;&lt;li&gt;Pagination.&lt;/li&gt;&lt;li&gt;البحث.&lt;/li&gt;&lt;li&gt;الفلاتر.&lt;/li&gt;&lt;li&gt;الترتيب.&lt;/li&gt;&lt;li&gt;الإحصائيات.&lt;/li&gt;&lt;li&gt;الصلاحيات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;ما هي Seeders؟&lt;/h3&gt;&lt;p&gt;الـ &lt;strong&gt;Seeder&lt;/strong&gt; هو كلاس مسؤول عن إدخال بيانات إلى قاعدة البيانات.&lt;/p&gt;&lt;p&gt;توجد Seeders في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/seeders
&lt;/pre&gt;&lt;p&gt;ويأتي Laravel افتراضيًا مع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DatabaseSeeder.php
&lt;/pre&gt;&lt;p&gt;يمكن استخدامه كنقطة البداية لتشغيل Seeders أخرى.&lt;/p&gt;&lt;p&gt;وفقًا للتوثيق الرسمي لـ Laravel 13، يمكن إنشاء Seeder باستخدام &lt;code inline=""&gt;make:seeder&lt;/code&gt;، ويحتوي Seeder عادةً على method باسم &lt;code inline=""&gt;run()&lt;/code&gt; يتم تنفيذها عند تشغيل أمر &lt;code inline=""&gt;db:seed&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;إنشاء أول Factory&lt;/h3&gt;&lt;p&gt;لنفرض أن لدينا Model باسم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;يمكننا إنشاء Factory باستخدام Artisan:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:factory ArticleFactory
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء الملف داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/factories
&lt;/pre&gt;&lt;p&gt;ليصبح لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/
└── factories/
    └── ArticleFactory.php
&lt;/pre&gt;&lt;h3&gt;إنشاء Factory مع Model&lt;/h3&gt;&lt;p&gt;إذا كنت تنشئ Model جديدًا من البداية، يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article --factory
&lt;/pre&gt;&lt;p&gt;أو يمكنك استخدام الخيار المختصر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article -f
&lt;/pre&gt;&lt;p&gt;وبذلك يساعدك Artisan في إنشاء Model وFactory.&lt;/p&gt;&lt;h3&gt;فهم ArticleFactory&lt;/h3&gt;&lt;p&gt;بعد إنشاء Factory، ستجد كلاس مشابهًا لهذا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class ArticleFactory extends Factory
{
    public function definition(): array
    {
        return [
            //
        ];
    }
}
&lt;/pre&gt;&lt;p&gt;أهم جزء هنا هو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;definition()
&lt;/pre&gt;&lt;p&gt;هذه الدالة تحدد البيانات الافتراضية التي سيتم استخدامها عند إنشاء Article باستخدام Factory.&lt;/p&gt;&amp;gt;&lt;h3&gt;كتابة البيانات داخل Factory&lt;/h3&gt;&lt;p&gt;لنفترض أن جدول &lt;code inline=""&gt;articles&lt;/code&gt; يحتوي على:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;title&lt;/li&gt;&lt;li&gt;slug&lt;/li&gt;&lt;li&gt;content&lt;/li&gt;&lt;li&gt;is_published&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;يمكن كتابة Factory مثل التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class ArticleFactory extends Factory
{
    public function definition(): array
    {
        return [
            'title' =&amp;gt; fake()-&amp;gt;sentence(),
            'slug' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;slug(),
            'content' =&amp;gt; fake()-&amp;gt;paragraphs(3, true),
            'is_published' =&amp;gt; fake()-&amp;gt;boolean(),
        ];
    }
}
&lt;/pre&gt;&lt;p&gt;الآن أصبح لدينا قالب لإنشاء المقالات.&lt;/p&gt;&lt;h3&gt;ماذا يفعل fake()؟&lt;/h3&gt;&lt;p&gt;لننظر إلى كل سطر.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;إنشاء عنوان&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; fake()-&amp;gt;sentence(),
&lt;/pre&gt;&lt;p&gt;ينشئ عنوانًا عشوائيًا.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;إنشاء Slug&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'slug' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;slug(),
&lt;/pre&gt;&lt;p&gt;ينشئ slug عشوائيًا، مع استخدام &lt;code inline=""&gt;unique()&lt;/code&gt; لتجنب تكرار القيمة أثناء عملية التوليد.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;إنشاء المحتوى&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'content' =&amp;gt; fake()-&amp;gt;paragraphs(3, true),
&lt;/pre&gt;&lt;p&gt;ينشئ عدة فقرات نصية.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;إنشاء قيمة Boolean&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'is_published' =&amp;gt; fake()-&amp;gt;boolean(),
&lt;/pre&gt;&lt;p&gt;يمكن أن تنتج:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;true
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;false
&lt;/pre&gt;&lt;h3&gt;استخدام Factory لإنشاء سجل واحد&lt;/h3&gt;&lt;p&gt;بعد تجهيز Factory، يمكننا استخدامه من خلال Model.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Models\Article;

$article = Article::factory()-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء Article جديد وإدخاله في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;توثيق Laravel يوضح استخدام &lt;code inline=""&gt;factory()&lt;/code&gt; على Models لإنشاء نماذج واختبارها أو استخدامها ضمن عمليات seeding.&lt;/p&gt;&lt;h3&gt;إنشاء عدة سجلات&lt;/h3&gt;&lt;p&gt;يمكننا إنشاء أكثر من سجل باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;count(10)-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء 10 مقالات.&lt;/p&gt;&lt;p&gt;ويمكنك تغيير الرقم حسب حاجتك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;count(50)-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;count(100)-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وهذه واحدة من أهم فوائد Factories.&lt;/p&gt;&lt;h3&gt;الفرق بين create وmake&lt;/h3&gt;&lt;p&gt;هناك فرق مهم بين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;make();
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;make()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ينشئ Model في الذاكرة فقط دون حفظه في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::factory()-&amp;gt;make();
&lt;/pre&gt;&lt;p&gt;يمكنك استخدامه عندما تريد التعامل مع الكائن دون إدخاله إلى قاعدة البيانات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;create()&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ينشئ Model ويحفظه في قاعدة البيانات.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::factory()-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;لذلك عند تجهيز بيانات حقيقية داخل قاعدة البيانات، ستستخدم &lt;code inline=""&gt;create()&lt;/code&gt; غالبًا.&lt;/p&gt;&lt;h3&gt;استخدام Factory مع العلاقات&lt;/h3&gt;&lt;p&gt;وهنا تبدأ قوة Factories بالظهور بشكل أكبر.&lt;/p&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
articles
&lt;/pre&gt;&lt;p&gt;والعلاقة هي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User hasMany Articles
Article belongsTo User
&lt;/pre&gt;&lt;p&gt;أي أن المستخدم يمكن أن يمتلك عدة مقالات.&lt;/p&gt;&lt;p&gt;إذا أردنا إنشاء User ومعه عدة Articles، يمكننا استخدام العلاقة التي عرفناها في الدرس السابق.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::factory()
    -&amp;gt;has(Article::factory()-&amp;gt;count(5))
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء مستخدم، ومعه 5 مقالات مرتبطة به.&lt;/p&gt;&lt;p&gt;هذه الطريقة مفيدة جدًا عندما يكون التطبيق يحتوي على بيانات مترابطة.&lt;/p&gt;&lt;p&gt;توثيق Laravel 13 يخصص قسمًا كاملًا لعلاقات Factories، ومنها علاقات &lt;code inline=""&gt;hasMany&lt;/code&gt; و&lt;code inline=""&gt;belongsTo&lt;/code&gt; و&lt;code inline=""&gt;many-to-many&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;إنشاء عدة Users مع المقالات&lt;/h3&gt;&lt;p&gt;يمكننا أيضًا إنشاء 10 مستخدمين، ولكل مستخدم 5 مقالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()
    -&amp;gt;count(10)
    -&amp;gt;has(Article::factory()-&amp;gt;count(5))
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;والنتيجة ستكون تقريبًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;10 Users
│
├── User 1
│   ├── Article
│   ├── Article
│   ├── Article
│   ├── Article
│   └── Article
│
├── User 2
│   ├── Article
│   ├── Article
│   ├── Article
│   ├── Article
│   └── Article
│
└── ...
&lt;/pre&gt;&lt;p&gt;أي 10 مستخدمين و50 مقالًا مرتبطًا بهم.&lt;/p&gt;&lt;h3&gt;إنشاء Seeder&lt;/h3&gt;&lt;p&gt;لننشئ Seeder خاصًا بالمقالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:seeder ArticleSeeder
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/seeders/ArticleSeeder.php
&lt;/pre&gt;&lt;p&gt;وسيكون هيكله الأساسي قريبًا من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    public function run(): void
    {
        //
    }
}
&lt;/pre&gt;&lt;h3&gt;إضافة Factory إلى Seeder&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;يمكننا الآن استخدام Article Factory داخل Seeder:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Seeders;

use App\Models\Article;
use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    public function run(): void
    {
        Article::factory()
            -&amp;gt;count(50)
            -&amp;gt;create();
    }
}
&lt;/pre&gt;&lt;p&gt;الآن عند تشغيل هذا Seeder سيتم إنشاء 50 مقالًا.&lt;/p&gt;&lt;h3&gt;تشغيل Seeder&lt;/h3&gt;&lt;p&gt;يمكن تشغيل الـ Seeder الرئيسي باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan db:seed
&lt;/pre&gt;&lt;p&gt;افتراضيًا يقوم Laravel بتشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DatabaseSeeder
&lt;/pre&gt;&lt;p&gt;والذي يمكنه بدوره تشغيل Seeders أخرى.&lt;/p&gt;&lt;p&gt;يمكن أيضًا تشغيل Seeder محدد باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan db:seed --class=ArticleSeeder
&lt;/pre&gt;&lt;p&gt;وهذه الأوامر موثقة رسميًا في Laravel 13.&lt;/p&gt;&lt;h3&gt;ما هو DatabaseSeeder؟&lt;/h3&gt;&lt;p&gt;داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/seeders
&lt;/pre&gt;&lt;p&gt;ستجد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DatabaseSeeder.php
&lt;/pre&gt;&lt;p&gt;يمكن اعتباره نقطة التجميع الرئيسية للـ Seeders.&lt;/p&gt;&lt;p&gt;بدلًا من وضع كل البيانات داخل ملف واحد، من الأفضل تقسيمها.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/seeders/
├── DatabaseSeeder.php
├── UserSeeder.php
├── ArticleSeeder.php
├── CategorySeeder.php
└── CommentSeeder.php
&lt;/pre&gt;&lt;p&gt;ثم يمكنك استدعاؤها من &lt;code inline=""&gt;DatabaseSeeder&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;استخدام call()&lt;/h3&gt;&lt;p&gt;يمكن كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function run(): void
{
    $this-&amp;gt;call([
        UserSeeder::class,
        CategorySeeder::class,
        ArticleSeeder::class,
        CommentSeeder::class,
    ]);
}
&lt;/pre&gt;&lt;p&gt;وبذلك يتم تشغيل Seeders بالترتيب المحدد.&lt;/p&gt;&lt;p&gt;يسمح Laravel باستخدام &lt;code inline=""&gt;call()&lt;/code&gt; لتقسيم عملية seeding إلى عدة Seeders بدل وضع كل شيء داخل &lt;code inline=""&gt;DatabaseSeeder&lt;/code&gt; واحد.&lt;/p&gt;&lt;h3&gt;لماذا ترتيب Seeders مهم؟&lt;/h3&gt;&lt;p&gt;تخيل أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Users
Categories
Articles
Comments
&lt;/pre&gt;&lt;p&gt;والمقال يحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
category_id
&lt;/pre&gt;&lt;p&gt;والتعليق يحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;article_id
user_id
&lt;/pre&gt;&lt;p&gt;إذًا من المنطقي أن ننشئ البيانات بهذا الترتيب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Users
   ↓
Categories
   ↓
Articles
   ↓
Comments
&lt;/pre&gt;&lt;p&gt;لأن البيانات اللاحقة تعتمد على البيانات السابقة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال عملي كامل&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنقم ببناء سيناريو صغير لموقع مقالات.&lt;/p&gt;&lt;p&gt;لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
Category
Article
Comment
&lt;/pre&gt;&lt;p&gt;والعلاقات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 └── hasMany Articles

Category
 └── hasMany Articles

Article
 ├── belongsTo User
 ├── belongsTo Category
 └── hasMany Comments

Comment
 ├── belongsTo User
 └── belongsTo Article
&lt;/pre&gt;&lt;p&gt;هذه العلاقات مبنية على نفس مفهوم Eloquent Relationships الذي تعلمناه في الدرس العاشر.&lt;/p&gt;&lt;h3&gt;UserFactory&lt;/h3&gt;&lt;p&gt;يمكن أن يكون لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function definition(): array
{
    return [
        'name' =&amp;gt; fake()-&amp;gt;name(),
        'email' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;safeEmail(),
        'email_verified_at' =&amp;gt; now(),
        'password' =&amp;gt; bcrypt('password'),
    ];
}
&lt;/pre&gt;&lt;p&gt;وبذلك يمكن إنشاء المستخدمين تلقائيًا.&lt;/p&gt;&lt;h3&gt;CategoryFactory&lt;/h3&gt;&lt;p&gt;يمكن إنشاء Factory للتصنيفات:&lt;/p&gt;&lt;pre&gt;&lt;code class="language-bash"&gt;php artisan make:factory CategoryFactory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function definition(): array
{
    return [
        'name' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;words(2, true),
        'slug' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;slug(),
    ];
}
&lt;/pre&gt;&lt;h3&gt;ArticleFactory مع العلاقات&lt;/h3&gt;&lt;p&gt;إذا كان جدول &lt;code inline=""&gt;articles&lt;/code&gt; يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
category_id
title
slug
content
is_published
&lt;/pre&gt;&lt;p&gt;يمكن أن نكتب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function definition(): array
{
    return [
        'user_id' =&amp;gt; User::factory(),
        'category_id' =&amp;gt; Category::factory(),
        'title' =&amp;gt; fake()-&amp;gt;sentence(),
        'slug' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;slug(),
        'content' =&amp;gt; fake()-&amp;gt;paragraphs(4, true),
        'is_published' =&amp;gt; fake()-&amp;gt;boolean(),
    ];
}
&lt;/pre&gt;&lt;p&gt;بهذه الطريقة يستطيع Factory إنشاء User وCategory عند الحاجة وربطهما بالمقال.&lt;/p&gt;&lt;p&gt;لكن في التطبيقات الكبيرة، قد تفضّل إنشاء المستخدمين والتصنيفات بشكل مستقل ثم إعادة استخدامهم، خصوصًا عندما تريد التحكم في عدد العلاقات بدل إنشاء سجلات جديدة لكل Article.&lt;/p&gt;&lt;h3&gt;إعادة استخدام سجلات موجودة&lt;/h3&gt;&lt;p&gt;لنفرض أننا أنشأنا 10 Users و5 Categories:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()-&amp;gt;count(10)-&amp;gt;create();
Category::factory()-&amp;gt;count(5)-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;بعد ذلك يمكننا استخدام سجلات موجودة عند إنشاء Articles.&lt;/p&gt;&lt;p&gt;على سبيل المثال، يمكنك اختيار مستخدم وتصنيف موجودين ثم استخدام معرفاتهما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::inRandomOrder()-&amp;gt;first();
$category = Category::inRandomOrder()-&amp;gt;first();

Article::factory()-&amp;gt;create([
    'user_id' =&amp;gt; $user-&amp;gt;id,
    'category_id' =&amp;gt; $category-&amp;gt;id,
]);
&lt;/pre&gt;&lt;p&gt;هذه الفكرة مفيدة عندما تريد التحكم بشكل أكبر في البيانات.&lt;/p&gt;&lt;h3&gt;استخدام Factory States&lt;/h3&gt;&lt;p&gt;أحيانًا نحتاج إلى أنواع مختلفة من السجلات.&lt;/p&gt;&lt;p&gt;مثلًا في المقالات قد نحتاج إلى:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;مقالات منشورة.&lt;/li&gt;&lt;li&gt;مقالات غير منشورة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;بدل إنشاء Factory منفصل لكل نوع، يمكننا استخدام &lt;strong&gt;States&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function published(): static
{
    return $this-&amp;gt;state(fn (array $attributes) =&amp;gt; [
        'is_published' =&amp;gt; true,
    ]);
}
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()
    -&amp;gt;published()
    -&amp;gt;count(10)
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وهكذا أصبح لدينا 10 مقالات منشورة.&lt;/p&gt;&lt;p&gt;يمكن أيضًا إنشاء حالة للمقالات غير المنشورة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function draft(): static
{
    return $this-&amp;gt;state(fn (array $attributes) =&amp;gt; [
        'is_published' =&amp;gt; false,
    ]);
}
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()
    -&amp;gt;draft()
    -&amp;gt;count(5)
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;توثيق Laravel 13 يدعم Factory States كطريقة لتغيير الحالة الافتراضية للبيانات عند إنشاء النماذج.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال على Seeder احترافي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;يمكن أن يصبح &lt;code inline=""&gt;ArticleSeeder&lt;/code&gt; مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Seeders;

use App\Models\Article;
use App\Models\Category;
use App\Models\User;
use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    public function run(): void
    {
        User::factory()-&amp;gt;count(10)-&amp;gt;create();

        Category::factory()-&amp;gt;count(5)-&amp;gt;create();

        Article::factory()-&amp;gt;count(50)-&amp;gt;create();
    }
}
&lt;/pre&gt;&lt;p&gt;هذا المثال مناسب للتعلم، لكن في مشروع حقيقي قد ترغب في التحكم بشكل أكبر في العلاقات وربط المقالات بمستخدمين وتصنيفات موجودة بالفعل.&lt;/p&gt;&lt;h3&gt;migrate --seed&lt;/h3&gt;&lt;p&gt;أثناء التطوير ستحتاج أحيانًا إلى إعادة بناء قاعدة البيانات من البداية.&lt;/p&gt;&lt;p&gt;يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;هذا الأمر يقوم بإسقاط الجداول ثم تشغيل الـ migrations من جديد، وبعد ذلك تشغيل الـ seeders. لذلك يجب استخدامه بحذر، خصوصًا إذا كانت قاعدة البيانات تحتوي على بيانات مهمة. Laravel يوضح رسميًا أن &lt;code inline=""&gt;migrate:fresh&lt;/code&gt; يحذف جميع الجداول ثم يعيد تشغيل الـ migrations، ويمكن دمجه مع &lt;code inline=""&gt;--seed&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;أثناء التطوير يمكن أن يكون هذا الأمر مفيدًا جدًا.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;ثم تصبح لديك قاعدة بيانات جديدة تحتوي على بيانات تجريبية.&lt;/p&gt;&lt;h3&gt;الفرق بين migrate وseed&lt;/h3&gt;&lt;p&gt;من المهم جدًا فهم الفرق.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;migrate&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;المigrations مسؤولة عن &lt;strong&gt;بنية قاعدة البيانات&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إنشاء جدول users
إنشاء جدول articles
إضافة عمود slug
إضافة Foreign Key
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;seed&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;الـ Seeders مسؤولة عن &lt;strong&gt;البيانات الموجودة داخل الجداول&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إنشاء 10 Users
إنشاء 50 Articles
إنشاء Categories
إنشاء Comments
&lt;/pre&gt;&lt;p&gt;بمعنى آخر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Migration
    ↓
بناء الجداول

Seeder
    ↓
إضافة البيانات
&lt;/pre&gt;&lt;h3&gt;الفرق بين &lt;em&gt;Factory&lt;/em&gt; وSeeder وFaker&lt;/h3&gt;&lt;p&gt;من أكثر الأشياء التي تسبب ارتباكًا للمبتدئين الخلط بين هذه المفاهيم.&lt;/p&gt;&lt;p&gt;يمكن تلخيصها كالتالي:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;الأداة&lt;/th&gt;&lt;th&gt;وظيفتها&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Migration&lt;/td&gt;&lt;td&gt;إنشاء وتعديل بنية قاعدة البيانات&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Model&lt;/td&gt;&lt;td&gt;التعامل مع بيانات الجدول&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Factory&lt;/td&gt;&lt;td&gt;تحديد شكل البيانات التجريبية&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Faker&lt;/td&gt;&lt;td&gt;توليد قيم وهمية&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Seeder&lt;/td&gt;&lt;td&gt;تشغيل وإدخال البيانات إلى قاعدة البيانات&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Faker
  ↓
ينشئ قيمًا عشوائية

Factory
  ↓
يحدد شكل Article

Seeder
  ↓
يطلب إنشاء 50 Article

Database
  ↓
تخزن البيانات
&lt;/pre&gt;&lt;h3&gt;إنشاء بيانات مرتبطة&lt;/h3&gt;&lt;p&gt;لنستخدم العلاقات التي تعلمناها في الدرس السابق.&lt;/p&gt;&lt;p&gt;لنفترض:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()
    -&amp;gt;has(Article::factory()-&amp;gt;count(5))
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;هنا لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 │
 ├── Article
 ├── Article
 ├── Article
 ├── Article
 └── Article
&lt;/pre&gt;&lt;p&gt;يمكنك توسيع الفكرة لإنشاء بيانات كبيرة مترابطة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()
    -&amp;gt;count(20)
    -&amp;gt;has(Article::factory()-&amp;gt;count(5))
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;يمكن أن ينتج عن ذلك 20 مستخدمًا مع 5 مقالات لكل مستخدم.&lt;/p&gt;&lt;h3&gt;Factories وMany-to-Many&lt;/h3&gt;&lt;p&gt;يمكن استخدام Factories أيضًا مع العلاقات Many-to-Many.&lt;/p&gt;&lt;p&gt;مثلًا إذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
roles
role_user
&lt;/pre&gt;&lt;p&gt;يمكن إنشاء المستخدم والأدوار وربطها باستخدام إمكانيات Factories الخاصة بالعلاقات.&lt;/p&gt;&lt;p&gt;الفكرة الأساسية هي أن Factory لا يقتصر على إنشاء سجل منفرد، بل يمكنه المساعدة في إنشاء مجموعات من البيانات المرتبطة.&lt;/p&gt;&lt;p&gt;وهذا مهم جدًا في التطبيقات الكبيرة، لأن البيانات الواقعية غالبًا لا تكون عبارة عن جداول منفصلة، وإنما مجموعة من العلاقات.&lt;/p&gt;&lt;h3&gt;استخدام بيانات Faker بحذر&lt;/h3&gt;&lt;p&gt;Faker ممتاز للبيانات التجريبية، لكن يجب أن تتذكر أن هذه البيانات ليست بيانات حقيقية.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;fake()-&amp;gt;email()
&lt;/pre&gt;&lt;p&gt;ينشئ بريدًا وهميًا.&lt;/p&gt;&lt;p&gt;لا يجب أن تعتمد على هذه البيانات باعتبارها بيانات مستخدمين حقيقيين.&lt;/p&gt;&lt;p&gt;كما يجب ألا تستخدم Seeder يحتوي على بيانات تجريبية بشكل عشوائي على قاعدة بيانات Production.&lt;/p&gt;&lt;h3&gt;مشكلة شائعة: تشغيل Seeder على Production&lt;/h3&gt;&lt;p&gt;تخيل أنك كتبت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;ثم نفذته على قاعدة بيانات Production.&lt;/p&gt;&lt;p&gt;هذا قد يؤدي إلى حذف الجداول والبيانات الموجودة ثم إعادة بنائها.&lt;/p&gt;&lt;p&gt;لذلك يجب الانتباه جدًا إلى البيئة التي تعمل عليها.&lt;/p&gt;&lt;p&gt;Laravel يطلب تأكيدًا عند تنفيذ بعض عمليات seeding في بيئة production، ويمكن استخدام &lt;code inline=""&gt;--force&lt;/code&gt; لتجاوز التأكيد، ولذلك يجب عدم استخدامه إلا عندما تكون متأكدًا من النتيجة.&lt;/p&gt;&lt;h3&gt;مشكلة شائعة: العلاقات لا تعمل&lt;/h3&gt;&lt;p&gt;إذا حاولت إنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وكان Factory يحتاج إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;لكن لم يتم توفيره، فقد تواجه مشكلة حسب بنية الجدول والعلاقة.&lt;/p&gt;&lt;p&gt;لذلك تأكد من أن Factory يعرف كيفية إنشاء أو الحصول على السجلات المرتبطة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'user_id' =&amp;gt; User::factory(),
&lt;/pre&gt;&lt;p&gt;يمكن أن يوفر مستخدمًا مرتبطًا عند إنشاء Article.&lt;/p&gt;&lt;h3&gt;مشكلة شائعة: أسماء الأعمدة&lt;/h3&gt;&lt;p&gt;يجب أن تتطابق البيانات التي تضعها داخل Factory مع أسماء الأعمدة في Migration.&lt;/p&gt;&lt;p&gt;إذا كان لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('title');
&lt;/pre&gt;&lt;p&gt;يجب أن تستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; fake()-&amp;gt;sentence(),
&lt;/pre&gt;&lt;p&gt;وليس:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'name' =&amp;gt; fake()-&amp;gt;sentence(),
&lt;/pre&gt;&lt;p&gt;إلا إذا كان لديك فعلًا عمود باسم &lt;code inline=""&gt;name&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;مشكلة شائعة: Unique&lt;/h3&gt;&lt;p&gt;إذا كان لديك عمود فريد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('slug')-&amp;gt;unique();
&lt;/pre&gt;&lt;p&gt;فلا تريد إنشاء نفس القيمة عشرات المرات.&lt;/p&gt;&lt;p&gt;لذلك يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'slug' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;slug(),
&lt;/pre&gt;&lt;p&gt;وبذلك تقل احتمالية إنتاج قيم مكررة أثناء إنشاء البيانات.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;مثال عملي نهائي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;لنضع كل شيء معًا.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;ArticleFactory&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Factories;

use Illuminate\Database\Eloquent\Factories\Factory;

class ArticleFactory extends Factory
{
    public function definition(): array
    {
        return [
            'title' =&amp;gt; fake()-&amp;gt;sentence(),
            'slug' =&amp;gt; fake()-&amp;gt;unique()-&amp;gt;slug(),
            'content' =&amp;gt; fake()-&amp;gt;paragraphs(4, true),
            'is_published' =&amp;gt; fake()-&amp;gt;boolean(),
        ];
    }

    public function published(): static
    {
        return $this-&amp;gt;state(fn (array $attributes) =&amp;gt; [
            'is_published' =&amp;gt; true,
        ]);
    }
}
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;ArticleSeeder&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Seeders;

use App\Models\Article;
use Illuminate\Database\Seeder;

class ArticleSeeder extends Seeder
{
    public function run(): void
    {
        Article::factory()
            -&amp;gt;published()
            -&amp;gt;count(20)
            -&amp;gt;create();

        Article::factory()
            -&amp;gt;count(10)
            -&amp;gt;create();
    }
}
&lt;/pre&gt;&lt;p&gt;النتيجة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;20 Published Articles
+
10 Draft/Random Articles
=
30 Articles
&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;DatabaseSeeder&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace Database\Seeders;

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run(): void
    {
        $this-&amp;gt;call([
            ArticleSeeder::class,
        ]);
    }
}
&lt;/pre&gt;&lt;p&gt;ثم نفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;إذا كانت الـ migrations والـ Models والـ Factories مكتملة بشكل صحيح، فسيتم بناء قاعدة البيانات من جديد ثم تشغيل Seeder.&lt;/p&gt;&lt;h3&gt;كيف تستخدم البيانات في التطبيق؟&lt;/h3&gt;&lt;p&gt;بعد إنشاء البيانات، يمكنك استخدامها مع Eloquent كما تعلمنا في الدرس التاسع.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::latest()-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;ثم إرسالها إلى View:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return view('articles.index', compact('articles'));
&lt;/pre&gt;&lt;p&gt;وفي Blade:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@foreach ($articles as $article)
    &amp;lt;article&amp;gt;
        &amp;lt;h2&amp;gt;{{ $article-&amp;gt;title }}&amp;lt;/h2&amp;gt;

        &amp;lt;p&amp;gt;{{ $article-&amp;gt;content }}&amp;lt;/p&amp;gt;
    &amp;lt;/article&amp;gt;
@endforeach
&lt;/pre&gt;&lt;p&gt;وهكذا أصبح لدينا دورة كاملة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Migration
   ↓
Database Tables
   ↓
Model
   ↓
Factory
   ↓
Faker
   ↓
Seeder
   ↓
Database Records
   ↓
Controller
   ↓
View
&lt;/pre&gt;&lt;p&gt;وهذه الدورة مهمة جدًا لفهم كيفية بناء تطبيق Laravel متكامل.&lt;/p&gt;&lt;h3&gt;Factories والاختبارات&lt;/h3&gt;&lt;p&gt;Factories لا تستخدم فقط أثناء التطوير.&lt;/p&gt;&lt;p&gt;يمكن استخدامها أيضًا داخل الاختبارات لإنشاء البيانات المطلوبة قبل اختبار جزء من التطبيق.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::factory()-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;ثم يمكنك تنفيذ طلب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$response = $this-&amp;gt;actingAs($user)
    -&amp;gt;get('/articles');
&lt;/pre&gt;&lt;p&gt;وجود Factory يجعل تجهيز بيانات الاختبار أسهل بكثير.&lt;/p&gt;&lt;p&gt;Laravel يوفر أدوات لاستخدام Factories وSeeders ضمن اختبارات قاعدة البيانات أيضًا.&lt;/p&gt;&lt;h3&gt;أفضل الممارسات&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;اجعل Factory بسيطًا&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;ضع البيانات الافتراضية الأساسية داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;definition()
&lt;/pre&gt;&lt;p&gt;ولا تجعل Factory معقدًا دون حاجة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;استخدم States للحالات المختلفة&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;بدل إنشاء Factory لكل حالة، استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;published()
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;draft()
&lt;/pre&gt;&lt;p&gt;أو حالات أخرى تناسب التطبيق.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;قسم Seeders&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;إذا كان المشروع كبيرًا، لا تضع كل شيء داخل:&lt;/p&gt;&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DatabaseSeeder.php
&lt;/pre&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;UserSeeder
CategorySeeder
ArticleSeeder
CommentSeeder
&lt;/pre&gt;&lt;p&gt;ثم استدعها من &lt;code inline=""&gt;DatabaseSeeder&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;انتبه للعلاقات&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;عند إنشاء بيانات مترابطة، تأكد من أن السجلات المطلوبة موجودة وأن Foreign Keys صحيحة.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;لا تستخدم بيانات الاختبار بشكل عشوائي في Production&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;بيانات Faker مخصصة أساسًا للبيانات التجريبية والتطوير والاختبار.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;تمرين عملي&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;حان وقت التطبيق.&lt;/p&gt;&lt;p&gt;قم بإنشاء نظام صغير للمقالات يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
Category
Article
&lt;/pre&gt;&lt;p&gt;ثم نفذ الخطوات التالية.&lt;/p&gt;&lt;p&gt;الخطوة الأولى&lt;/p&gt;&lt;p&gt;أنشئ Factory للتصنيف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:factory CategoryFactory
&lt;/pre&gt;&lt;p&gt;الخطوة الثانية&lt;/p&gt;&lt;p&gt;اجعل Factory ينشئ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;name
slug
&lt;/pre&gt;&lt;p&gt;الخطوة الثالثة&lt;/p&gt;&lt;p&gt;أنشئ Seeder:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:seeder CategorySeeder
&lt;/pre&gt;&lt;p&gt;الخطوة الرابعة&lt;/p&gt;&lt;p&gt;أنشئ 10 تصنيفات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Category::factory()
    -&amp;gt;count(10)
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;الخطوة الخامسة&lt;/p&gt;&lt;p&gt;أنشئ 20 مستخدمًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()
    -&amp;gt;count(20)
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;الخطوة السادسة&lt;/p&gt;&lt;p&gt;أنشئ 100 مقال.&lt;/p&gt;&lt;p&gt;اجعل كل مقال مرتبطًا بمستخدم وتصنيف.&lt;/p&gt;&lt;p&gt;الخطوة السابعة&lt;/p&gt;&lt;p&gt;شغّل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;الخطوة الثامنة&lt;/p&gt;&lt;p&gt;أنشئ Route يعرض المقالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/articles', function () {
    $articles = Article::latest()-&amp;gt;get();

    return view('articles.index', compact('articles'));
});
&lt;/pre&gt;&lt;p&gt;ثم أنشئ View لعرض المقالات.&lt;/p&gt;&lt;p&gt;بهذا التمرين ستكون قد ربطت تقريبًا جميع المفاهيم التي تعلمتها حتى الآن.&lt;/p&gt;&lt;h3&gt;ماذا تعلمنا في هذا الدرس؟&lt;/h3&gt;&lt;p&gt;في هذا الدرس تعرفنا على طريقة إنشاء البيانات التجريبية في Laravel باستخدام مجموعة من الأدوات المتكاملة.&lt;/p&gt;&lt;p&gt;تعلمنا أن:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Factory&lt;/strong&gt; تحدد شكل البيانات التي سيتم إنشاؤها.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Faker&lt;/strong&gt; يوفر بيانات وهمية مثل الأسماء والبريد الإلكتروني والنصوص.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Seeder&lt;/strong&gt; مسؤول عن تشغيل عملية إدخال البيانات إلى قاعدة البيانات.&lt;/p&gt;&lt;p&gt;وتعلمنا إنشاء Factory باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:factory ArticleFactory
&lt;/pre&gt;&lt;p&gt;وإنشاء Seeder باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:seeder ArticleSeeder
&lt;/pre&gt;&lt;p&gt;وتعلمنا إنشاء سجل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وإنشاء عدة سجلات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()-&amp;gt;count(50)-&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وتعلمنا استخدام العلاقات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::factory()
    -&amp;gt;has(Article::factory()-&amp;gt;count(5))
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;كما تعرفنا على Factory States مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::factory()
    -&amp;gt;published()
    -&amp;gt;count(10)
    -&amp;gt;create();
&lt;/pre&gt;&lt;p&gt;وتعلمنا تشغيل Seeders:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan db:seed
&lt;/pre&gt;&lt;p&gt;أو Seeder محدد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan db:seed --class=ArticleSeeder
&lt;/pre&gt;&lt;p&gt;وتعلمنا إعادة بناء قاعدة البيانات مع تشغيل البيانات التجريبية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;أصبحت الآن قادرًا على تجهيز قاعدة بيانات Laravel بكمية كبيرة من البيانات دون الحاجة إلى إدخال كل سجل يدويًا.&lt;/p&gt;&lt;p&gt;وهذا مهم جدًا في المشاريع الحقيقية، لأن المطور يحتاج باستمرار إلى بيانات تساعده على اختبار التطبيق وتصميم الواجهات وتجربة البحث وPagination والعلاقات ولوحات الإدارة.&lt;/p&gt;&lt;p&gt;يمكن تصور الأدوات التي تعلمناها حتى الآن بهذه الصورة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Migrations
    ↓
إنشاء الجداول
    ↓
Models + Eloquent
    ↓
التعامل مع البيانات
    ↓
Relationships
    ↓
ربط الجداول
    ↓
Factories + Faker
    ↓
توليد بيانات تجريبية
    ↓
Seeders
    ↓
تعبئة قاعدة البيانات
&lt;/pre&gt;&lt;p&gt;في الدرس القادم سنبدأ بالانتقال إلى جزء مهم جدًا في بناء تطبيقات Laravel العملية، وهو &lt;strong&gt;Authentication والمستخدمون وتسجيل الدخول والتسجيل وإدارة الجلسات&lt;/strong&gt;، حتى نبدأ في بناء تطبيقات تحتوي على مستخدمين حقيقيين وصلاحيات وسلوكيات مرتبطة بالحسابات.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/9154505850998750500/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-factories-seeders-faker.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/9154505850998750500" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/9154505850998750500" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-factories-seeders-faker.html" rel="alternate" title="إنشاء بيانات تجريبية بسهولة Factories في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNNqWbLSmHm6i1IgdSf9K2vj0FngDX-_GC0qf8gXZ5hlNfzOKXKxGiBX029ScgusQm6w6FOsAR6XIHbGgxiI0A3K9tra1uvnYNeqVtnQUklc9XJ3-GsyF4Cmo8cjmwdJquzvsbE-wlXCc_dEPqWqc5QOH2PukSpBh1QVtlrKhQeSfSqhQ7YWIVb5_f2G5Y/s72-c/imageedit_1_8808712567.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-3999698078183468346</id><published>2026-09-24T09:55:49.447+03:00</published><updated>2026-09-24T09:55:49.448+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">العلاقات بين الجداول HasMany في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE6qxfFAcTIMAOq1R8Wr4YoPWoifZ7yYvbK42tLSqQ8bsZjK-x5GPNOVQdGycI7JaD5QEuCbIuCMTJXWCBoDyL1d-BLD5q0z3EmgniC4OL2hTof77JFKvJ9h39nz9BO5BG1OXe-l6DlCBBWsx8jK3cAkGO8uJxZEMu_ltO3qEQ5nJvXXhQfvS1sE8pNFek/s640/imageedit_1_7810565842.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="الدرس العاشر: العلاقات بين الجداول في Laravel Eloquent – HasMany وBelongsTo وManyToMany" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE6qxfFAcTIMAOq1R8Wr4YoPWoifZ7yYvbK42tLSqQ8bsZjK-x5GPNOVQdGycI7JaD5QEuCbIuCMTJXWCBoDyL1d-BLD5q0z3EmgniC4OL2hTof77JFKvJ9h39nz9BO5BG1OXe-l6DlCBBWsx8jK3cAkGO8uJxZEMu_ltO3qEQ5nJvXXhQfvS1sE8pNFek/s1600/imageedit_1_7810565842.webp" title="الدرس العاشر: العلاقات بين الجداول في Laravel Eloquent – HasMany وBelongsTo وManyToMany" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;العلاقات بين الجداول في Laravel Eloquent – HasMany وBelongsTo وManyToMany&lt;/h3&gt;&lt;p&gt;بعد أن تعرّفنا في الدروس السابقة على &lt;a href="https://www.nusurtech.ca/2026/09/laravel-models-eloquent.html" target="_blank"&gt;قواعد البيانات&lt;/a&gt; و &lt;a href="https://www.nusurtech.ca/2026/09/laravel-database-migrations.html" target="_blank"&gt;Migrations&lt;/a&gt;، وتعلمنا أساسيات Models و Eloquent، حان الوقت للانتقال إلى واحدة من أهم النقاط في بناء تطبيقات Laravel الحقيقية: &lt;strong&gt;العلاقات بين الجداول&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;في أي تطبيق تقريبًا، نادرًا ما تكون الجداول منفصلة تمامًا عن بعضها.&lt;/p&gt;&lt;p&gt;في موقع مقالات مثلًا، لدينا مستخدم يمكن أن يكتب عدة مقالات، والمقال الواحد ينتمي إلى مستخدم واحد، والمقال يمكن أن يحتوي على عدة تعليقات، والتعليق ينتمي إلى مقال معين.&lt;/p&gt;&lt;p&gt;وفي متجر إلكتروني، لدينا:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;مستخدمون.&lt;/li&gt;&lt;li&gt;منتجات.&lt;/li&gt;&lt;li&gt;تصنيفات.&lt;/li&gt;&lt;li&gt;طلبات.&lt;/li&gt;&lt;li&gt;تفاصيل الطلبات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;وقد يكون المنتج موجودًا في عدة طلبات، والطلب يحتوي على عدة منتجات، والمستخدم لديه عدة طلبات.&lt;/p&gt;&lt;p&gt;بدون العلاقات، سنضطر إلى كتابة الكثير من الاستعلامات المعقدة يدويًا.&lt;/p&gt;&lt;p&gt;أما مع &lt;strong&gt;Eloquent ORM&lt;/strong&gt;، فيمكننا تعريف العلاقات داخل Models، ثم التعامل معها بطريقة بسيطة وواضحة.&lt;/p&gt;&lt;p&gt;Laravel Eloquent يدعم مجموعة واسعة من العلاقات، من بينها One to One وOne to Many وMany to Many، بالإضافة إلى العلاقات عبر نموذج وسيط والعلاقات Polymorphic.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنركز على العلاقات التي يحتاجها المبتدئ أولًا، ثم نأخذ نظرة على العلاقات المتقدمة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما المقصود بالعلاقات بين الجداول؟&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا جدولين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
articles
&lt;/pre&gt;&lt;p&gt;ولدينا البيانات التالية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users

id | name
1  | أحمد
2  | محمد
&lt;/pre&gt;&lt;p&gt;وجدول المقالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles

id | user_id | title
1  | 1       | تعلم Laravel
2  | 1       | شرح Routing
3  | 2       | تعلم PHP
&lt;/pre&gt;&lt;p&gt;لاحظ أن المقال الأول والثاني يحتويان على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id = 1
&lt;/pre&gt;&lt;p&gt;وهذا يعني أن كلا المقالين يتبعان المستخدم الذي يحمل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id = 1
&lt;/pre&gt;&lt;p&gt;إذن لدينا علاقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
  |
  | hasMany
  ↓
Articles
&lt;/pre&gt;&lt;p&gt;وفي الاتجاه العكسي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
   |
   | belongsTo
   ↓
User
&lt;/pre&gt;&lt;p&gt;هذه هي فكرة العلاقات الأساسية في Eloquent.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نستخدم Eloquent Relationships؟&lt;/h3&gt;&lt;p&gt;بدلًا من كتابة استعلامات SQL طويلة للحصول على المقالات الخاصة بالمستخدم، يمكننا تعريف العلاقة داخل Model.&lt;/p&gt;&lt;p&gt;مثلًا داخل &lt;code inline=""&gt;User&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function articles()
{
    return $this-&amp;gt;hasMany(Article::class);
}
&lt;/pre&gt;&lt;p&gt;ثم يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;articles;
&lt;/pre&gt;&lt;p&gt;للحصول على مقالات المستخدم.&lt;/p&gt;&lt;p&gt;وبالعكس داخل &lt;code inline=""&gt;Article&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function user()
{
    return $this-&amp;gt;belongsTo(User::class);
}
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;user;
&lt;/pre&gt;&lt;p&gt;للحصول على المستخدم الذي كتب المقال.&lt;/p&gt;&lt;p&gt;Laravel يجعل العلاقات عبارة عن Methods داخل Eloquent Models، وهذه العلاقات يمكن استخدامها أيضًا كـ Query Builders لإضافة شروط وترتيب واستعلامات أخرى.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أنواع العلاقات الأساسية&lt;/h3&gt;&lt;p&gt;هناك عدة أنواع من العلاقات في Laravel، لكن أهم ما يجب أن تتعلمه في البداية هو:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;One to One&lt;/li&gt;&lt;li&gt;One to Many&lt;/li&gt;&lt;li&gt;Belongs To&lt;/li&gt;&lt;li&gt;Many to Many&lt;/li&gt;&lt;li&gt;Has Many Through&lt;/li&gt;&lt;li&gt;Polymorphic Relationships&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;سنبدأ بالأنواع الأربعة الأساسية.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;One to One علاقة واحد إلى واحد&lt;/h4&gt;&lt;p&gt;في علاقة One to One يكون لكل سجل سجل واحد مرتبط به.&lt;/p&gt;&lt;p&gt;مثال بسيط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
  ↓
Phone
&lt;/pre&gt;&lt;p&gt;يمكن أن يكون لكل مستخدم هاتف واحد.&lt;/p&gt;&lt;p&gt;في قاعدة البيانات قد يكون لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users

id | name
1  | أحمد
2  | محمد
&lt;/pre&gt;&lt;p&gt;وجدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;phones

id | user_id | phone_number
1  | 1       | 555123
2  | 2       | 555456
&lt;/pre&gt;&lt;p&gt;هنا كل مستخدم لديه هاتف واحد.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;تعريف Has One&lt;/h4&gt;&lt;p&gt;داخل &lt;code inline=""&gt;User&lt;/code&gt; Model:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasOne;

class User extends Model
{
    public function phone(): HasOne
    {
        return $this-&amp;gt;hasOne(Phone::class);
    }
}
&lt;/pre&gt;&lt;p&gt;لاحظ أننا استخدمنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$this-&amp;gt;hasOne(Phone::class);
&lt;/pre&gt;&lt;p&gt;أي أن User لديه Phone واحد.&lt;/p&gt;&lt;p&gt;بعد ذلك يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::find(1);

$phone = $user-&amp;gt;phone;
&lt;/pre&gt;&lt;p&gt;وهنا سيحاول Eloquent الحصول على الهاتف المرتبط بالمستخدم.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;تعريف العلاقة العكسية BelongsTo&lt;/h4&gt;&lt;p&gt;داخل &lt;code inline=""&gt;Phone&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Phone extends Model
{
    public function user(): BelongsTo
    {
        return $this-&amp;gt;belongsTo(User::class);
    }
}
&lt;/pre&gt;&lt;p&gt;الآن يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$phone = Phone::find(1);

$user = $phone-&amp;gt;user;
&lt;/pre&gt;&lt;p&gt;وهكذا يستطيع الهاتف الوصول إلى المستخدم المرتبط به.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;One to Many – واحد إلى عدة&lt;/h4&gt;&lt;p&gt;هذه من أهم العلاقات في Laravel.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 |
 | hasMany
 ↓
Articles
&lt;/pre&gt;&lt;p&gt;المستخدم الواحد يمكن أن يكتب عدة مقالات.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;أحمد
 ├── تعلم Laravel
 ├── شرح Controllers
 └── شرح Eloquent
&lt;/pre&gt;&lt;p&gt;بينما المقال الواحد ينتمي إلى مستخدم واحد.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;إنشاء علاقة hasMany&lt;/h4&gt;&lt;p&gt;داخل &lt;code inline=""&gt;User&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\Relations\HasMany;

public function articles(): HasMany
{
    return $this-&amp;gt;hasMany(Article::class);
}
&lt;/pre&gt;&lt;p&gt;الآن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::find(1);

$articles = $user-&amp;gt;articles;
&lt;/pre&gt;&lt;p&gt;سيحصل Eloquent على المقالات المرتبطة بهذا المستخدم.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;قراءة المقالات&lt;/h4&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;foreach ($user-&amp;gt;articles as $article) {
    echo $article-&amp;gt;title;
}
&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم لديه ثلاث مقالات، فسيتم المرور عليها واحدة تلو الأخرى.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام العلاقة كـ Query Builder&lt;/h3&gt;&lt;p&gt;العلاقات في Eloquent ليست مجرد خصائص للقراءة.&lt;/p&gt;&lt;p&gt;يمكنك استدعاء Method العلاقة باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;articles()
&lt;/pre&gt;&lt;p&gt;ثم إضافة شروط.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = $user-&amp;gt;articles()
    -&amp;gt;where('is_published', true)
    -&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = $user-&amp;gt;articles()
    -&amp;gt;latest()
    -&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;وهذا من نقاط القوة المهمة في Eloquent Relationships، لأن العلاقات نفسها توفر Query Builder يمكن تقييده بشروط إضافية.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;BelongsTo العلاقة العكسية&lt;/h3&gt;&lt;p&gt;إذا كان User لديه عدة Articles، فإن Article ينتمي إلى User.&lt;/p&gt;&lt;p&gt;داخل &lt;code inline=""&gt;Article&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\Relations\BelongsTo;

public function user(): BelongsTo
{
    return $this-&amp;gt;belongsTo(User::class);
}
&lt;/pre&gt;&lt;p&gt;بعد ذلك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);

echo $article-&amp;gt;user-&amp;gt;name;
&lt;/pre&gt;&lt;p&gt;يمكننا الآن الوصول إلى اسم صاحب المقال بسهولة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أين يوجد Foreign Key؟&lt;/h3&gt;&lt;p&gt;عادة يكون لدينا في جدول &lt;code inline=""&gt;articles&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
user_id
title
content
&lt;/pre&gt;&lt;p&gt;ويكون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;هو المفتاح الأجنبي الذي يشير إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users.id
&lt;/pre&gt;&lt;p&gt;أي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.user_id
        ↓
users.id
&lt;/pre&gt;&lt;p&gt;وهذه النقطة مهمة جدًا لفهم العلاقة.&lt;/p&gt;&lt;p&gt;إذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles

id | user_id | title
1  | 5       | Laravel
&lt;/pre&gt;&lt;p&gt;فهذا يعني أن المقال رقم &lt;code inline=""&gt;1&lt;/code&gt; يتبع المستخدم رقم &lt;code inline=""&gt;5&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;كيف يعرف Laravel اسم Foreign Key؟&lt;/h3&gt;&lt;p&gt;عند كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return $this-&amp;gt;belongsTo(User::class);
&lt;/pre&gt;&lt;p&gt;يحاول Eloquent عادة استنتاج اسم المفتاح الأجنبي من اسم الـ Model.&lt;/p&gt;&lt;p&gt;في حالة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
&lt;/pre&gt;&lt;p&gt;يكون المتوقع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;ولهذا لا نحتاج غالبًا إلى كتابة اسم العمود يدويًا إذا اتبعنا conventions الخاصة بـ Laravel.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تحديد Foreign Key بشكل يدوي&lt;/h3&gt;&lt;p&gt;إذا كان اسم العمود مختلفًا، يمكننا تحديده:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return $this-&amp;gt;belongsTo(
    User::class,
    'author_id'
);
&lt;/pre&gt;&lt;p&gt;هنا أصبح اسم المفتاح:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;author_id
&lt;/pre&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;ويمكن أيضًا تحديد المفتاح الأساسي الأب إذا كان مختلفًا عن &lt;code inline=""&gt;id&lt;/code&gt;. توثيق Laravel يوضح أن &lt;code inline=""&gt;belongsTo&lt;/code&gt; يقبل تحديد الـ foreign key والـ owner key عند الحاجة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #0c343d;"&gt;مثال كامل User وArticle&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لننشئ العلاقة بشكل كامل.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;User Model&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;

class User extends Model
{
    public function articles(): HasMany
    {
        return $this-&amp;gt;hasMany(Article::class);
    }
}
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;Article Model&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Article extends Model
{
    public function user(): BelongsTo
    {
        return $this-&amp;gt;belongsTo(User::class);
    }
}
&lt;/pre&gt;&lt;p&gt;الآن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 |
 | hasMany
 ↓
Article
&lt;/pre&gt;&lt;p&gt;والاتجاه العكسي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
 |
 | belongsTo
 ↓
User
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;Many to Many – علاقة متعدد إلى متعدد&lt;/h3&gt;&lt;p&gt;هذه العلاقة مهمة جدًا في المشاريع الكبيرة.&lt;/p&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Users
Roles
&lt;/pre&gt;&lt;p&gt;والمستخدم الواحد يمكن أن يمتلك عدة Roles.&lt;/p&gt;&lt;p&gt;وفي نفس الوقت، الـ Role الواحد يمكن أن يكون مرتبطًا بعدة Users.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Ahmed
 ├── Admin
 └── Editor

Mohamed
 ├── Editor
 └── Author
&lt;/pre&gt;&lt;p&gt;إذن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User ↔ Role
&lt;/pre&gt;&lt;p&gt;وهي Many to Many.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نحتاج جدولًا وسيطًا؟&lt;/h3&gt;&lt;p&gt;لا يمكننا وضع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role_id
&lt;/pre&gt;&lt;p&gt;داخل &lt;code inline=""&gt;users&lt;/code&gt; إذا كان المستخدم يمكن أن يمتلك عدة Roles.&lt;/p&gt;&lt;p&gt;ولا يمكننا وضع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;داخل &lt;code inline=""&gt;roles&lt;/code&gt; إذا كان الـ Role يمكن أن يرتبط بعدة مستخدمين.&lt;/p&gt;&lt;p&gt;لذلك نستخدم جدولًا وسيطًا.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
roles
role_user
&lt;/pre&gt;&lt;p&gt;ويحتوي جدول &lt;code inline=""&gt;role_user&lt;/code&gt; على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
role_id
&lt;/pre&gt;&lt;p&gt;توثيق Laravel يستخدم هذا النمط للعلاقات Many to Many، ويشير إلى أن جدول الـ intermediate table يكون عادة باسم يجمع أسماء النموذجين بترتيب أبجدي مثل &lt;code inline=""&gt;role_user&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء belongsToMany&lt;/h3&gt;&lt;p&gt;داخل &lt;code inline=""&gt;User&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\Relations\BelongsToMany;

public function roles(): BelongsToMany
{
    return $this-&amp;gt;belongsToMany(Role::class);
}
&lt;/pre&gt;&lt;p&gt;الآن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user = User::find(1);

$roles = $user-&amp;gt;roles;
&lt;/pre&gt;&lt;p&gt;سيحصل Eloquent على الأدوار المرتبطة بالمستخدم.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;العلاقة العكسية&lt;/h3&gt;&lt;p&gt;داخل &lt;code inline=""&gt;Role&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\Relations\BelongsToMany;

public function users(): BelongsToMany
{
    return $this-&amp;gt;belongsToMany(User::class);
}
&lt;/pre&gt;&lt;p&gt;وبالتالي يمكننا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$role = Role::find(1);

$users = $role-&amp;gt;users;
&lt;/pre&gt;&lt;p&gt;وهكذا نستطيع التنقل في الاتجاهين.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;جدول Pivot&lt;/h3&gt;&lt;p&gt;الجدول الوسيط في Many to Many يسمى غالبًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Pivot Table
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role_user
&lt;/pre&gt;&lt;p&gt;ويحتوي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
role_id
&lt;/pre&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role_user

user_id | role_id
1       | 1
1       | 2
2       | 2
2       | 3
&lt;/pre&gt;&lt;p&gt;هذا يعني:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User 1 → Role 1
User 1 → Role 2

User 2 → Role 2
User 2 → Role 3
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;إضافة علاقة Many to Many&lt;/h3&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;roles()-&amp;gt;attach($roleId);
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;roles()-&amp;gt;attach(2);
&lt;/pre&gt;&lt;p&gt;وهذا يضيف ارتباطًا بين المستخدم والـ Role.&lt;/p&gt;&lt;p&gt;يمكن أيضًا ربط أكثر من Role:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;roles()-&amp;gt;attach([1, 2, 3]);
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;حذف علاقة من Pivot&lt;/h3&gt;&lt;p&gt;إذا أردنا إزالة ارتباط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;roles()-&amp;gt;detach(2);
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;roles()-&amp;gt;detach([1, 2]);
&lt;/pre&gt;&lt;p&gt;وهذا يحذف الارتباط من جدول Pivot دون حذف الـ Role نفسه.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام sync()&lt;/h3&gt;&lt;p&gt;إذا أردت أن تجعل Roles الخاصة بالمستخدم مطابقة تمامًا لقائمة معينة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;roles()-&amp;gt;sync([1, 2, 3]);
&lt;/pre&gt;&lt;p&gt;فسيقوم Laravel بتحديث جدول Pivot بحيث تصبح العلاقات الحالية متوافقة مع هذه القائمة.&lt;/p&gt;&lt;p&gt;هذه الطريقة مفيدة جدًا عند التعامل مع نماذج الصلاحيات أو التصنيفات أو الوسوم.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;بيانات إضافية في Pivot&lt;/h3&gt;&lt;p&gt;أحيانًا لا يحتوي جدول Pivot على مفتاحين فقط.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;role_user

user_id
role_id
assigned_by
created_at
updated_at
&lt;/pre&gt;&lt;p&gt;يمكننا طلب بيانات إضافية من Pivot.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return $this-&amp;gt;belongsToMany(Role::class)
    -&amp;gt;withPivot('assigned_by');
&lt;/pre&gt;&lt;p&gt;وبعد الحصول على Role:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$role-&amp;gt;pivot-&amp;gt;assigned_by;
&lt;/pre&gt;&lt;p&gt;يمكن أيضًا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;-&amp;gt;withTimestamps()
&lt;/pre&gt;&lt;p&gt;إذا كان جدول Pivot يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;created_at
updated_at
&lt;/pre&gt;&lt;p&gt;وتدعم Eloquent التعامل مع هذه الأعمدة تلقائيًا عند تعريف العلاقة بهذه الطريقة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Eager Loading&lt;/h3&gt;&lt;p&gt;الآن وصلنا إلى نقطة مهمة جدًا في الأداء.&lt;/p&gt;&lt;p&gt;لنفترض أننا نريد عرض 100 مقال، وكل مقال نريد عرض اسم صاحبه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::all();

foreach ($articles as $article) {
    echo $article-&amp;gt;user-&amp;gt;name;
}
&lt;/pre&gt;&lt;p&gt;قد يؤدي هذا إلى تنفيذ استعلام للحصول على المقالات، ثم استعلامات إضافية للحصول على المستخدمين عند الوصول إلى العلاقة.&lt;/p&gt;&lt;p&gt;وهذا يمكن أن يؤدي إلى مشكلة تسمى:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;N + 1 Query Problem&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Laravel يوفر Eager Loading لتجنب هذا النوع من المشاكل.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام with()&lt;/h3&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::with('user')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;الآن نطلب من Laravel تحميل العلاقة مع المقالات.&lt;/p&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;foreach ($articles as $article) {
    echo $article-&amp;gt;user-&amp;gt;name;
}
&lt;/pre&gt;&lt;p&gt;وبذلك يكون التعامل مع البيانات أكثر كفاءة في الحالات المناسبة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Eager Loading لأكثر من علاقة&lt;/h3&gt;&lt;p&gt;يمكنك تحميل عدة علاقات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::with([
    'user',
    'comments',
])-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;إذا كان &lt;code inline=""&gt;Article&lt;/code&gt; لديه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user
comments
&lt;/pre&gt;&lt;p&gt;فسيتم تحميل العلاقات المطلوبة مع الاستعلام الأساسي.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Eager Loading المتداخل&lt;/h3&gt;&lt;p&gt;يمكن أيضًا تحميل علاقات داخل علاقات.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::with('user.profile')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;الفكرة هنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
  ↓
User
  ↓
Profile
&lt;/pre&gt;&lt;p&gt;وهذا مفيد عندما يكون لديك أكثر من مستوى في البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Lazy Loading&lt;/h3&gt;&lt;p&gt;عندما تكتب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;user
&lt;/pre&gt;&lt;p&gt;فإن Eloquent يستطيع تحميل العلاقة عند الوصول إليها.&lt;/p&gt;&lt;p&gt;وهذا يسمى:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Lazy Loading&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أي أن العلاقة لا يتم تحميلها إلا عند الحاجة إليها.&lt;/p&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::with('user')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;فهو مثال على:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Eager Loading&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أي أنك تطلب من Laravel تحميل العلاقة مسبقًا.&lt;/p&gt;&lt;p&gt;الفرق بينهما مهم جدًا عندما تبدأ التعامل مع عدد كبير من السجلات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Querying Relationship&lt;/h3&gt;&lt;p&gt;يمكنك البحث عن النماذج بناءً على وجود علاقة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::has('comments')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;هذا يمكن استخدامه للحصول على المقالات التي لديها تعليقات.&lt;/p&gt;&lt;p&gt;ويمكن أيضًا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::whereHas('comments', function ($query) {
    $query-&amp;gt;where('approved', true);
})-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;وهنا نطلب المقالات التي لديها تعليقات تحقق شرطًا معينًا.&lt;/p&gt;&lt;p&gt;Eloquent يوفر &lt;code inline=""&gt;has&lt;/code&gt; و&lt;code inline=""&gt;whereHas&lt;/code&gt; للاستعلام بناءً على وجود العلاقات وشروطها.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #660000;"&gt;مثال عملي: نظام المقالات والتعليقات&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لنقم ببناء مثال بسيط.&lt;/p&gt;&lt;p&gt;لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
articles
comments
&lt;/pre&gt;&lt;p&gt;العلاقات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 |
 | hasMany
 ↓
Articles
 |
 | hasMany
 ↓
Comments
&lt;/pre&gt;&lt;p&gt;والاتجاهات العكسية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
 |
 | belongsTo
 ↓
User
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Comment
 |
 | belongsTo
 ↓
Article
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;User Model&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function articles(): HasMany
{
    return $this-&amp;gt;hasMany(Article::class);
}
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;Article Model&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function user(): BelongsTo
{
    return $this-&amp;gt;belongsTo(User::class);
}

public function comments(): HasMany
{
    return $this-&amp;gt;hasMany(Comment::class);
}
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;Comment Model&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function article(): BelongsTo
{
    return $this-&amp;gt;belongsTo(Article::class);
}
&lt;/pre&gt;&lt;p&gt;الآن يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;user;
&lt;/pre&gt;&lt;p&gt;للحصول على صاحب المقال.&lt;/p&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;comments;
&lt;/pre&gt;&lt;p&gt;للحصول على التعليقات.&lt;/p&gt;&lt;p&gt;ومن التعليق:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$comment-&amp;gt;article;
&lt;/pre&gt;&lt;p&gt;للحصول على المقال.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام العلاقات داخل Controller&lt;/h3&gt;&lt;p&gt;يمكن أن نستخدم العلاقات داخل Controller بطريقة بسيطة.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function show(Article $article)
{
    $article-&amp;gt;load('user', 'comments');

    return view('articles.show', compact('article'));
}
&lt;/pre&gt;&lt;p&gt;هنا استخدمنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;load()
&lt;/pre&gt;&lt;p&gt;لتحميل العلاقات على Model موجود بالفعل.&lt;/p&gt;&lt;p&gt;ثم داخل Blade:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;h1&amp;gt;{{ $article-&amp;gt;title }}&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;
    الكاتب: {{ $article-&amp;gt;user-&amp;gt;name }}
&amp;lt;/p&amp;gt;

@foreach ($article-&amp;gt;comments as $comment)
    &amp;lt;p&amp;gt;{{ $comment-&amp;gt;content }}&amp;lt;/p&amp;gt;
@endforeach
&lt;/pre&gt;&lt;p&gt;وهكذا أصبح لدينا صفحة مقال تعرض:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;عنوان المقال.&lt;/li&gt;&lt;li&gt;اسم الكاتب.&lt;/li&gt;&lt;li&gt;التعليقات.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Has Many Through&lt;/h3&gt;&lt;p&gt;هناك حالات نحتاج فيها إلى الوصول إلى بيانات من خلال علاقة وسيطة.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Country
   ↓
Users
   ↓
Articles
&lt;/pre&gt;&lt;p&gt;قد نريد الحصول على جميع المقالات الخاصة بدولة معينة من خلال المستخدمين.&lt;/p&gt;&lt;p&gt;هنا يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;hasManyThrough
&lt;/pre&gt;&lt;p&gt;مثال مبسط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function articles(): HasManyThrough
{
    return $this-&amp;gt;hasManyThrough(
        Article::class,
        User::class
    );
}
&lt;/pre&gt;&lt;p&gt;هذا النوع من العلاقات يسمح للنموذج بالوصول إلى نماذج بعيدة من خلال نموذج وسيط. Laravel يوفر &lt;code inline=""&gt;hasManyThrough&lt;/code&gt; لهذا النوع من السيناريوهات.&lt;/p&gt;&lt;p&gt;لكن لا تقلق إذا بدت لك هذه العلاقة صعبة الآن؛ في أغلب المشاريع التعليمية الأولى ستستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;hasOne
hasMany
belongsTo
belongsToMany
&lt;/pre&gt;&lt;p&gt;بشكل أكبر.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;متى أستخدم كل علاقة؟&lt;/h3&gt;&lt;p&gt;يمكنك حفظها بهذه الطريقة:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;HasOne&lt;/b&gt;&lt;/p&gt;&lt;p&gt;عندما يكون لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User → Phone
&lt;/pre&gt;&lt;p&gt;أي واحد إلى واحد.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;HasMany&lt;/b&gt;&lt;/p&gt;&lt;p&gt;عندما يكون لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User → Articles
&lt;/pre&gt;&lt;p&gt;أي واحد إلى عدة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;BelongsTo&lt;/b&gt;&lt;/p&gt;&lt;p&gt;عندما يكون السجل الحالي ينتمي إلى سجل أب.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article → User
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;BelongsToMany&lt;/b&gt;&lt;/p&gt;&lt;p&gt;عندما يكون الطرفان يمكن أن يرتبطا بعدة سجلات من الطرف الآخر.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User ↔ Roles
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Articles ↔ Tags
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;مثال عملي باستخدام Articles وCategories&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;categories
articles
&lt;/pre&gt;&lt;p&gt;وكل Category لديها عدة Articles:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Category
   |
   | hasMany
   ↓
Articles
&lt;/pre&gt;&lt;p&gt;داخل &lt;code inline=""&gt;Category&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function articles(): HasMany
{
    return $this-&amp;gt;hasMany(Article::class);
}
&lt;/pre&gt;&lt;p&gt;وفي &lt;code inline=""&gt;Article&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function category(): BelongsTo
{
    return $this-&amp;gt;belongsTo(Category::class);
}
&lt;/pre&gt;&lt;p&gt;ويكون جدول &lt;code inline=""&gt;articles&lt;/code&gt; مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
category_id
title
content
&lt;/pre&gt;&lt;p&gt;ثم يمكننا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$category-&amp;gt;articles;
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;category;
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;العلاقة بين Migration وRelationship&lt;/h3&gt;&lt;p&gt;من المهم أن تفهم أن تعريف العلاقة داخل Model وحده لا ينشئ Foreign Key في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function user(): BelongsTo
{
    return $this-&amp;gt;belongsTo(User::class);
}
&lt;/pre&gt;&lt;p&gt;هذا يخبر Eloquent بكيفية الوصول إلى المستخدم.&lt;/p&gt;&lt;p&gt;لكن قاعدة البيانات نفسها يجب أن تحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;وفي Migration يمكن أن نكتب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;foreignId('user_id')
    -&amp;gt;constrained();
&lt;/pre&gt;&lt;p&gt;إذن لدينا جزآن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Migration
   ↓
Database Structure
   ↓
Foreign Key
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Model
   ↓
Eloquent Relationship
   ↓
Application Logic
&lt;/pre&gt;&lt;p&gt;يجب أن يعمل الجزآن معًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أخطاء شائعة في العلاقات&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;1 - نسيان Foreign Key&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان Article يعتمد على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;لكن العمود غير موجود في قاعدة البيانات، فلن تعمل العلاقة بالشكل المتوقع.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;2 - كتابة اسم Model خاطئ&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::class
&lt;/pre&gt;&lt;p&gt;تأكد من وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Models/Article.php
&lt;/pre&gt;&lt;p&gt;واستخدام Namespace صحيح.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;3 - الخلط بين hasMany وbelongsTo&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User → Articles
&lt;/pre&gt;&lt;p&gt;فاستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;hasMany()
&lt;/pre&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article → User
&lt;/pre&gt;&lt;p&gt;فاستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;belongsTo()
&lt;/pre&gt;&lt;p&gt;قاعدة سهلة للحفظ:&lt;/p&gt;&lt;p&gt;الأب لديه أبناء = &lt;code inline=""&gt;hasMany&lt;/code&gt;&lt;/p&gt;&lt;p&gt;الابن ينتمي إلى أب = &lt;code inline=""&gt;belongsTo&lt;/code&gt;&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;4 - تحميل العلاقات داخل Loop بطريقة غير محسوبة&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان لديك عدد كبير من المقالات وكتبت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::all();

foreach ($articles as $article) {
    echo $article-&amp;gt;user-&amp;gt;name;
}
&lt;/pre&gt;&lt;p&gt;فانتبه إلى مشكلة N+1 المحتملة.&lt;/p&gt;&lt;p&gt;في مثل هذه الحالة غالبًا يكون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::with('user')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;أفضل من ناحية الاستعلامات، لأن Eager Loading مصمم لمعالجة هذا النوع من السيناريوهات.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #800180;"&gt;تمرين عملي&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;قم ببناء نظام صغير للمقالات يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
articles
comments
categories
&lt;/pre&gt;&lt;p&gt;واجعل العلاقات كالتالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 └── hasMany Articles

Article
 ├── belongsTo User
 ├── belongsTo Category
 └── hasMany Comments

Category
 └── hasMany Articles

Comment
 └── belongsTo Article
&lt;/pre&gt;&lt;p&gt;ثم أنشئ Models والعلاقات المناسبة.&lt;/p&gt;&lt;p&gt;بعد ذلك جرّب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$user-&amp;gt;articles;
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;user;
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;category;
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;comments;
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$comment-&amp;gt;article;
&lt;/pre&gt;&lt;p&gt;وأخيرًا حاول تحميل المقالات مع الكاتب والتعليقات باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::with([
    'user',
    'comments',
])-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;إذا تمكنت من تنفيذ هذا التمرين، فأنت بدأت فعليًا في فهم كيفية بناء العلاقات داخل تطبيق Laravel حقيقي.&lt;/p&gt;&lt;p&gt;في هذا الدرس تعلمنا كيف نتعامل مع العلاقات بين جداول قاعدة البيانات باستخدام Eloquent.&lt;/p&gt;&lt;p&gt;تعرفنا على العلاقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;hasOne()
&lt;/pre&gt;&lt;p&gt;والتي تستخدم عندما يكون هناك سجل واحد مرتبط بسجل آخر.&lt;/p&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;hasMany()
&lt;/pre&gt;&lt;p&gt;للعلاقة واحد إلى عدة.ء&lt;/p&gt;&lt;p&gt;وتعلمنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;belongsTo()
&lt;/pre&gt;&lt;p&gt;للعلاقة العكسية، عندما يكون النموذج الحالي تابعًا لنموذج آخر.&lt;/p&gt;&lt;p&gt;ثم تعرفنا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;belongsToMany()
&lt;/pre&gt;&lt;p&gt;للعلاقات Many to Many، واستخدمنا جدول Pivot لربط الطرفين.&lt;/p&gt;&lt;p&gt;كما تعلمنا كيفية استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;attach()
detach()
sync()
&lt;/pre&gt;&lt;p&gt;لإدارة العلاقات Many to Many.&lt;/p&gt;&lt;p&gt;وتعرفنا أيضًا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;with()
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;load()
&lt;/pre&gt;&lt;p&gt;لاستخدام Eager Loading وتقليل مشكلة N+1 Query.&lt;/p&gt;&lt;p&gt;وتعلمنا أن العلاقات في Eloquent لا تعني فقط إمكانية الوصول إلى البيانات، بل يمكن استخدامها أيضًا لبناء استعلامات أكثر قوة باستخدام Methods مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;whereHas()
has()
&lt;/pre&gt;&lt;p&gt;وأصبح لدينا الآن تصور واضح عن العلاقة بين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Database
   ↓
Migrations
   ↓
Models
   ↓
Relationships
   ↓
Controllers
   ↓
Views
&lt;/pre&gt;&lt;p&gt;وهذا هو الأساس الذي سنبني عليه بقية تطبيق Laravel.&lt;/p&gt;&lt;p&gt;بعد أن تعلمنا Models وEloquent والعلاقات بين الجداول، أصبحنا جاهزين للانتقال إلى جزء عملي مهم جدًا: &lt;strong&gt;Factories وSeeders&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;سنستخدمها لإنشاء بيانات تجريبية داخل قاعدة البيانات بدلًا من إدخال عشرات السجلات يدويًا.&lt;/p&gt;&lt;p&gt;وسنتعلم كيف ننشئ مستخدمين ومقالات وتعليقات تلقائيًا، وكيف نستخدم Faker لتوليد بيانات واقعية، وكيف نربط البيانات ببعضها باستخدام العلاقات التي تعلمناها في هذا الدرس.&lt;/p&gt;&lt;p&gt;وبذلك سننتقل من مجرد إنشاء الجداول والعلاقات إلى &lt;strong&gt;تعبئة قاعدة البيانات ببيانات حقيقية للاختبار والتطوير&lt;/strong&gt;.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/3999698078183468346/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-eloquent-relationships.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/3999698078183468346" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/3999698078183468346" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-eloquent-relationships.html" rel="alternate" title="العلاقات بين الجداول HasMany في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjE6qxfFAcTIMAOq1R8Wr4YoPWoifZ7yYvbK42tLSqQ8bsZjK-x5GPNOVQdGycI7JaD5QEuCbIuCMTJXWCBoDyL1d-BLD5q0z3EmgniC4OL2hTof77JFKvJ9h39nz9BO5BG1OXe-l6DlCBBWsx8jK3cAkGO8uJxZEMu_ltO3qEQ5nJvXXhQfvS1sE8pNFek/s72-c/imageedit_1_7810565842.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-8683547252748676732</id><published>2026-09-23T11:26:54.075+03:00</published><updated>2026-09-23T11:28:04.770+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">التعامل مع قاعدة البيانات بسهولة في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkJ72XA79wfU7GRTG2PMdNPjvtP_AW1YQJw79Cs9E7dSrTqYhVoiag6FftA5MfIa6j5-sapLAe88fLW26ZbL2osjvFC_iJBGyP23TP2rOcYbnv5x8tajD5JLirO7U0aou3YpUaV2ai3wtmzUH9dNI_7WlzQlUS0ObZWfHNfkhOZaI1-0gO_aPJkJngj-G/s640/imageedit_3_3884483211.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Forms ومعالجة بيانات المستخدم" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkJ72XA79wfU7GRTG2PMdNPjvtP_AW1YQJw79Cs9E7dSrTqYhVoiag6FftA5MfIa6j5-sapLAe88fLW26ZbL2osjvFC_iJBGyP23TP2rOcYbnv5x8tajD5JLirO7U0aou3YpUaV2ai3wtmzUH9dNI_7WlzQlUS0ObZWfHNfkhOZaI1-0gO_aPJkJngj-G/s1600/imageedit_3_3884483211.webp" title="Forms ومعالجة بيانات المستخدم" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;التعامل مع قاعدة البيانات بسهولة Models و Eloquent&lt;/h3&gt;&lt;p&gt;بعد أن تعلمنا في الدرس الثامن كيفية إنشاء قاعدة البيانات والجداول باستخدام &lt;strong&gt;Migrations&lt;/strong&gt;، أصبح لدينا الآن مكان لتخزين بيانات التطبيق.&lt;/p&gt;&lt;p&gt;لكن هناك سؤال مهم:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;كيف نتعامل مع هذه البيانات من داخل Laravel؟&lt;/li&gt;&lt;li&gt;كيف نضيف مقالًا جديدًا؟&lt;/li&gt;&lt;li&gt;كيف نعرض المقالات الموجودة؟&lt;/li&gt;&lt;li&gt;كيف نعدل مقالًا؟&lt;/li&gt;&lt;li&gt;كيف نحذف سجلًا؟&lt;/li&gt;&lt;li&gt;وهل يجب أن نكتب SQL يدويًا في كل مرة؟&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;الإجابة هي: &lt;strong&gt;Eloquent ORM&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;يعتبر Eloquent من أهم الأجزاء في Laravel، لأنه يوفر طريقة بسيطة ومنظمة للتعامل مع قواعد البيانات من خلال &lt;strong&gt;Models&lt;/strong&gt; بدلًا من كتابة استعلامات SQL بشكل مباشر في كل عملية.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنتعرف على Models وEloquent، وسنتعلم إنشاء Model، وربطه بجدول قاعدة البيانات، وقراءة البيانات، وإضافة سجلات جديدة، وتعديلها وحذفها، بالإضافة إلى أهم طرق البحث والاستعلام، وشرح Mass Assignment و&lt;code inline=""&gt;fillable&lt;/code&gt;، ثم سنبني مثالًا عمليًا كاملًا على نظام المقالات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو Eloquent ORM؟&lt;/h3&gt;&lt;p&gt;Eloquent هو نظام ORM مدمج داخل Laravel.&lt;/p&gt;&lt;p&gt;ORM اختصار لـ:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Object-Relational Mapping&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;أي أنه يسمح لنا بالتعامل مع سجلات قاعدة البيانات باستخدام Objects وModels في PHP بدلًا من التعامل مع SQL في كل مرة.&lt;/p&gt;&lt;p&gt;في Laravel، يكون لكل جدول عادة Model يمثل هذا الجدول. ومن خلال هذا Model يمكننا استرجاع البيانات وإضافتها وتعديلها وحذفها.&lt;/p&gt;&lt;p&gt;بدل أن نكتب استعلام SQL مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;SELECT * FROM articles;
&lt;/pre&gt;&lt;p&gt;يمكننا باستخدام Eloquent كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::all();
&lt;/pre&gt;&lt;p&gt;وبدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;SELECT * FROM articles WHERE id = 1;
&lt;/pre&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::find(1);
&lt;/pre&gt;&lt;p&gt;الفكرة ليست فقط تقليل عدد الأسطر، وإنما جعل كود التطبيق أكثر وضوحًا وتنظيمًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو Model؟&lt;/h3&gt;&lt;p&gt;الـ Model هو Class في Laravel يمثل نوعًا معينًا من البيانات.&lt;/p&gt;&lt;p&gt;مثلًا لدينا جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;يمكن أن يكون لدينا Model اسمه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Database Table
       ↓
   articles
       ↑
       |
     Article
      Model
&lt;/pre&gt;&lt;p&gt;ومن خلال &lt;code inline=""&gt;Article&lt;/code&gt; يمكننا التعامل مع بيانات جدول &lt;code inline=""&gt;articles&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;كذلك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
&lt;/pre&gt;&lt;p&gt;يمثله عادة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
&lt;/pre&gt;&lt;p&gt;وجدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;categories
&lt;/pre&gt;&lt;p&gt;يمثله:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Category
&lt;/pre&gt;&lt;p&gt;وهكذا.&lt;/p&gt;&lt;p&gt;توجد Models التي ينشئها Laravel عادة داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Models
&lt;/pre&gt;&lt;p&gt;وتقوم بتمديد &lt;code inline=""&gt;Illuminate\Database\Eloquent\Model&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء أول Model&lt;/h3&gt;&lt;p&gt;لنفترض أننا نريد إنشاء Model للمقالات.&lt;/p&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article
&lt;/pre&gt;&lt;p&gt;بعد تنفيذ الأمر سيظهر ملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Models/Article.php
&lt;/pre&gt;&lt;p&gt;وقد يكون محتواه الأساسي مشابهًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Article extends Model
{
    //
}
&lt;/pre&gt;&lt;p&gt;لاحظ أن الـ Model يرث من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Model
&lt;/pre&gt;&lt;p&gt;من Laravel.&lt;/p&gt;&lt;p&gt;وهذا هو الذي يمنحه قدرات Eloquent.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء Model مع Migration&lt;/h3&gt;&lt;p&gt;إذا كنت تريد إنشاء Model وMigration في نفس الوقت، يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article --migration
&lt;/pre&gt;&lt;p&gt;أو الاختصار:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article -m
&lt;/pre&gt;&lt;p&gt;وهذا سينشئ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Models/Article.php
&lt;/pre&gt;&lt;p&gt;بالإضافة إلى Migration داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/migrations
&lt;/pre&gt;&lt;p&gt;Laravel يوفر أيضًا خيارات أخرى لإنشاء Factory وSeeder وController وForm Requests مع Model واحد.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article -mfsc
&lt;/pre&gt;&lt;p&gt;يمكن أن ينشئ Model وMigration وFactory وSeeder وController.&lt;/p&gt;&lt;p&gt;وهذا مفيد عندما تبدأ مشروعًا جديدًا وتعرف أنك ستحتاج إلى هذه الملفات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;كيف يعرف Eloquent اسم الجدول؟&lt;/h3&gt;&lt;p&gt;هنا تظهر واحدة من أهم قواعد Laravel.&lt;/p&gt;&lt;p&gt;إذا كان لدينا Model اسمه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;فإن Eloquent يتوقع افتراضيًا أن يكون اسم الجدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;أي اسم Model بصيغة الجمع وsnake_case.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
users

Article
 ↓
articles

Category
 ↓
categories

BlogPost
 ↓
blog_posts
&lt;/pre&gt;&lt;p&gt;هذه الاتفاقيات تجعل Laravel قادرًا على معرفة اسم الجدول دون الحاجة إلى كتابته داخل كل Model.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تحديد اسم الجدول يدويًا&lt;/h3&gt;&lt;p&gt;أحيانًا يكون اسم الجدول مختلفًا عن Convention.&lt;/p&gt;&lt;p&gt;في Laravel 13 يمكن تحديد اسم الجدول باستخدام &lt;code inline=""&gt;Table&lt;/code&gt; Attribute:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\Attributes\Table;
use Illuminate\Database\Eloquent\Model;

#[Table('my_articles')]
class Article extends Model
{
    //
}
&lt;/pre&gt;&lt;p&gt;وبذلك سيستخدم Model جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;my_articles
&lt;/pre&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;في المشاريع التي تتبع Convention الخاصة بـ Laravel، غالبًا لن تحتاج إلى ذلك.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Primary Key&lt;/h3&gt;&lt;p&gt;يفترض Eloquent افتراضيًا أن المفتاح الأساسي للجدول يسمى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles

id
title
content
&lt;/pre&gt;&lt;p&gt;إذا كان الجدول يستخدم اسمًا مختلفًا للمفتاح الأساسي، يمكن تخصيص ذلك في Model باستخدام إعدادات الجدول المناسبة.&lt;/p&gt;&lt;p&gt;لكن في بداية تعلم Laravel، يفضل الالتزام بالـ Convention:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
&lt;/pre&gt;&lt;p&gt;لأن ذلك يجعل التعامل مع Eloquent أسهل.&lt;/p&gt;&lt;p&gt;Laravel يدعم أيضًا مفاتيح UUID وULID عند الحاجة، لكن هذه المواضيع يمكن تأجيلها إلى مرحلة متقدمة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Timestamps في Eloquent&lt;/h3&gt;&lt;p&gt;إذا كان جدولك يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;created_at
updated_at
&lt;/pre&gt;&lt;p&gt;فإن Eloquent يتعامل معهما تلقائيًا عند إنشاء وتعديل Model.&lt;/p&gt;&lt;p&gt;ولهذا السبب كنا نستخدم في Migration:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;timestamps();
&lt;/pre&gt;&lt;p&gt;فعندما تقوم بإنشاء سجل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;save();
&lt;/pre&gt;&lt;p&gt;يمكن لـ Eloquent تحديث:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;created_at
updated_at
&lt;/pre&gt;&lt;p&gt;تلقائيًا.&lt;/p&gt;&lt;p&gt;وهذا أحد الأسباب التي تجعل &lt;code inline=""&gt;timestamps()&lt;/code&gt; شائعًا جدًا في جداول Laravel.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;قراءة البيانات باستخدام Eloquent&lt;/h3&gt;&lt;p&gt;بعد إنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;يمكننا البدء في قراءة البيانات.&lt;/p&gt;&lt;p&gt;أبسط طريقة هي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::all();
&lt;/pre&gt;&lt;p&gt;هذا يعيد جميع المقالات الموجودة في جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;ثم يمكننا المرور عليها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;foreach ($articles as $article) {
    echo $article-&amp;gt;title;
}
&lt;/pre&gt;&lt;p&gt;الدالة &lt;code inline=""&gt;all()&lt;/code&gt; تعيد Collection من نماذج Eloquent، وليست مجرد Array عادية.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هي Collection؟&lt;/h3&gt;&lt;p&gt;عندما تنفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::all();
&lt;/pre&gt;&lt;p&gt;ستحصل على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Illuminate\Database\Eloquent\Collection
&lt;/pre&gt;&lt;p&gt;وهي مجموعة من Models.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::all();

foreach ($articles as $article) {
    echo $article-&amp;gt;title;
}
&lt;/pre&gt;&lt;p&gt;يمكن التعامل معها باستخدام العديد من أدوات Collections الموجودة في Laravel.&lt;/p&gt;&lt;p&gt;وهذا يجعل التعامل مع مجموعة البيانات مريحًا جدًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;البحث عن سجل باستخدام ID&lt;/h3&gt;&lt;p&gt;إذا كنت تعرف ID المقال، يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);
&lt;/pre&gt;&lt;p&gt;هذا يبحث عن المقال الذي يحمل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id = 1
&lt;/pre&gt;&lt;p&gt;إذا كان موجودًا، تحصل على Model.&lt;/p&gt;&lt;p&gt;وإذا لم يكن موجودًا، ستكون النتيجة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;null
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);

if ($article) {
    echo $article-&amp;gt;title;
}
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;findOrFail() Laravel&lt;/h3&gt;&lt;p&gt;أحيانًا لا نريد الحصول على &lt;code inline=""&gt;null&lt;/code&gt; إذا لم يوجد السجل.&lt;/p&gt;&lt;p&gt;بل نريد أن يتعامل Laravel مع الحالة كـ 404.&lt;/p&gt;&lt;p&gt;هنا يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::findOrFail(1);
&lt;/pre&gt;&lt;p&gt;إذا كان المقال موجودًا، نحصل عليه.&lt;/p&gt;&lt;p&gt;أما إذا لم يكن موجودًا، فإن Laravel يرمي &lt;code inline=""&gt;ModelNotFoundException&lt;/code&gt;، ويمكن أن ينتج عن ذلك استجابة HTTP من نوع 404 عندما لا يتم التقاط الاستثناء.&lt;/p&gt;&lt;p&gt;وهذا مفيد جدًا في Controllers.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function show($id)
{
    $article = Article::findOrFail($id);

    return view('articles.show', compact('article'));
}
&lt;/pre&gt;&lt;p&gt;بدل كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;if (!$article) {
    abort(404);
}
&lt;/pre&gt;&lt;p&gt;يمكننا الاعتماد على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;findOrFail()&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;first() Laravel&lt;/h3&gt;&lt;p&gt;إذا أردنا الحصول على أول سجل يطابق شرطًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::where('is_published', true)
    -&amp;gt;first();
&lt;/pre&gt;&lt;p&gt;أو يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::first();
&lt;/pre&gt;&lt;p&gt;للحصول على أول Model.&lt;/p&gt;&lt;p&gt;Laravel يوفر أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;firstWhere()
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::firstWhere('is_published', true);
&lt;/pre&gt;&lt;p&gt;وهذه الطرق مخصصة عندما نريد Model واحدًا بدل Collection كاملة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام where()&lt;/h3&gt;&lt;p&gt;من أهم أدوات Eloquent:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;where()
&lt;/pre&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('is_published', true)-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;هذا يعني:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;أحضر المقالات التي يكون فيها &lt;code inline=""&gt;is_published&lt;/code&gt; يساوي &lt;code inline=""&gt;true&lt;/code&gt;.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;مثال آخر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('title', 'Laravel')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;ويمكن استخدام أكثر من شرط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('is_published', true)
    -&amp;gt;where('category_id', 2)
    -&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;وهذا يجعل الاستعلامات سهلة القراءة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;where مع المقارنة&lt;/h3&gt;&lt;p&gt;يمكنك تحديد نوع المقارنة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('id', '&amp;gt;', 10)-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('views', '&amp;gt;=', 100)-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('status', '!=', 'draft')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;الصيغة العامة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;where(
    'column',
    'operator',
    'value'
)
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;orderBy()&lt;/h3&gt;&lt;p&gt;يمكن ترتيب النتائج.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::orderBy('created_at', 'desc')-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;يعني:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;أحضر المقالات مرتبة من الأحدث إلى الأقدم.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;ويمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;orderBy('title', 'asc')
&lt;/pre&gt;&lt;p&gt;للترتيب الأبجدي التصاعدي.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;latest()&lt;/h3&gt;&lt;p&gt;Laravel يوفر طريقة سهلة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::latest()-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;وهي مناسبة جدًا عندما تريد الحصول على السجلات الأحدث أولًا.&lt;/p&gt;&lt;p&gt;مثلًا في صفحة المقالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::latest()-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;ثم ترسلها إلى View:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return view('articles.index', compact('articles'));
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;limit()&lt;/h3&gt;&lt;p&gt;إذا كنت تريد عددًا محددًا من النتائج:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::latest()
    -&amp;gt;limit(10)
    -&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;هذا مفيد عندما تريد عرض آخر 10 مقالات مثلًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;count()&lt;/h3&gt;&lt;p&gt;يمكنك معرفة عدد السجلات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$count = Article::count();
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$count = Article::where('is_published', true)-&amp;gt;count();
&lt;/pre&gt;&lt;p&gt;وهذا مفيد في الإحصائيات ولوحات التحكم.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء سجل جديد باستخدام save()&lt;/h3&gt;&lt;p&gt;يمكن إنشاء Article جديد بهذه الطريقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = new Article;

$article-&amp;gt;title = 'تعلم Laravel';
$article-&amp;gt;slug = 'learn-laravel';
$article-&amp;gt;content = 'محتوى المقال';

$article-&amp;gt;save();
&lt;/pre&gt;&lt;p&gt;عند استدعاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;save()
&lt;/pre&gt;&lt;p&gt;سيقوم Eloquent بحفظ السجل في قاعدة البيانات، وتتم إدارة &lt;code inline=""&gt;created_at&lt;/code&gt; و&lt;code inline=""&gt;updated_at&lt;/code&gt; تلقائيًا إذا كانت timestamps مفعلة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء سجل باستخدام create()&lt;/h3&gt;&lt;p&gt;هناك طريقة مختصرة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::create([
    'title' =&amp;gt; 'تعلم Laravel',
    'slug' =&amp;gt; 'learn-laravel',
    'content' =&amp;gt; 'محتوى المقال',
]);
&lt;/pre&gt;&lt;p&gt;لكن هناك نقطة أمنية مهمة جدًا.&lt;/p&gt;&lt;p&gt;عند استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;create()
&lt;/pre&gt;&lt;p&gt;يجب تحديد الحقول التي يسمح Laravel بتعبئتها باستخدام &lt;strong&gt;Mass Assignment protection&lt;/strong&gt;. في Laravel 13 يمكن استخدام &lt;code inline=""&gt;Fillable&lt;/code&gt; Attribute لتحديد الحقول المسموح بها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Mass Assignment&lt;/h3&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create($request-&amp;gt;all());
&lt;/pre&gt;&lt;p&gt;هذه الطريقة قد تكون خطيرة إذا كانت جميع حقول Request تمر مباشرة إلى Model.&lt;/p&gt;&lt;p&gt;لماذا؟&lt;/p&gt;&lt;p&gt;لأن المستخدم قد يرسل حقلًا لم تكن تقصده.&lt;/p&gt;&lt;p&gt;مثلًا إذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;is_admin
&lt;/pre&gt;&lt;p&gt;وأنت لا تريد للمستخدم التحكم فيه، فقد تصبح هناك مشكلة أمنية إذا سمحت بتمرير البيانات بلا تقييد.&lt;/p&gt;&lt;p&gt;ولهذا يوفر Laravel حماية Mass Assignment.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام Fillable في Laravel 13&lt;/h3&gt;&lt;p&gt;في Laravel 13 يمكن تعريف الحقول القابلة للتعبئة باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;

#[Fillable([
    'title',
    'slug',
    'content',
])]
class Article extends Model
{
    //
}
&lt;/pre&gt;&lt;p&gt;الآن يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create([
    'title' =&amp;gt; 'تعلم Laravel',
    'slug' =&amp;gt; 'learn-laravel',
    'content' =&amp;gt; 'محتوى المقال',
]);
&lt;/pre&gt;&lt;p&gt;بينما الحقول التي لم نسمح بها لن تكون ضمن Mass Assignment.&lt;/p&gt;
&lt;h4 style="text-align: right;"&gt;لماذا Mass Assignment مهمة؟&lt;/h4&gt;&lt;p&gt;تخيل أن جدول المستخدمين يحتوي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;name
email
password
is_admin
&lt;/pre&gt;&lt;p&gt;وأنت كتبت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User::create($request-&amp;gt;all());
&lt;/pre&gt;&lt;p&gt;قد يحاول شخص إرسال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;is_admin = true
&lt;/pre&gt;&lt;p&gt;إذا لم تكن قد ضبطت الحماية بشكل صحيح.&lt;/p&gt;&lt;p&gt;لذلك من المهم أن تحدد بوضوح ما الذي يسمح للتطبيق بتعبئته.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تحديث Model&lt;/h3&gt;&lt;p&gt;لنفرض أننا حصلنا على المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);
&lt;/pre&gt;&lt;p&gt;يمكننا تعديل عنوانه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;title = 'Laravel للمبتدئين';
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;save();
&lt;/pre&gt;&lt;p&gt;وبذلك يتم تحديث السجل في قاعدة البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام update()&lt;/h3&gt;&lt;p&gt;يمكن أيضًا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;update([
    'title' =&amp;gt; 'Laravel للمبتدئين',
]);
&lt;/pre&gt;&lt;p&gt;لكن عند استخدام &lt;code inline=""&gt;update()&lt;/code&gt; بهذه الطريقة يجب الانتباه أيضًا إلى Mass Assignment إذا كنت تستخدم مصفوفة attributes على Model.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;updateOrCreate()&lt;/h3&gt;&lt;p&gt;هناك حالات تريد فيها:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;إذا وجد السجل، قم بتحديثه، وإذا لم يوجد، أنشئه.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;هنا يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::updateOrCreate(
    [
        'slug' =&amp;gt; 'learn-laravel',
    ],
    [
        'title' =&amp;gt; 'تعلم Laravel',
        'content' =&amp;gt; 'محتوى المقال',
    ]
);
&lt;/pre&gt;&lt;p&gt;إذا وجد Laravel سجلًا مطابقًا للـ &lt;code inline=""&gt;slug&lt;/code&gt;، سيقوم بتحديثه.&lt;/p&gt;&lt;p&gt;أما إذا لم يجده، فسيقوم بإنشاء سجل جديد.&lt;/p&gt;&lt;p&gt;Laravel يوفر &lt;code inline=""&gt;updateOrCreate()&lt;/code&gt; لهذا النوع من العمليات، ويقوم بحفظ النتيجة مباشرة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;firstOrCreate()&lt;/h3&gt;&lt;p&gt;طريقة أخرى مفيدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::firstOrCreate([
    'slug' =&amp;gt; 'learn-laravel',
]);
&lt;/pre&gt;&lt;p&gt;إذا وجد السجل، يعيده.&lt;/p&gt;&lt;p&gt;وإذا لم يجده، ينشئ سجلًا جديدًا.&lt;/p&gt;&lt;p&gt;يمكن أيضًا تمرير بيانات إضافية عند الإنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::firstOrCreate(
    [
        'slug' =&amp;gt; 'learn-laravel',
    ],
    [
        'title' =&amp;gt; 'تعلم Laravel',
        'content' =&amp;gt; 'محتوى المقال',
    ]
);
&lt;/pre&gt;&lt;p&gt;Laravel يفرق بين &lt;code inline=""&gt;firstOrCreate()&lt;/code&gt; و&lt;code inline=""&gt;firstOrNew()&lt;/code&gt;؛ فـ &lt;code inline=""&gt;firstOrCreate()&lt;/code&gt; يحفظ السجل الجديد مباشرة، بينما &lt;code inline=""&gt;firstOrNew()&lt;/code&gt; يعيد Model جديدًا دون حفظه حتى تستدعي &lt;code inline=""&gt;save()&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;حذف سجل&lt;/h3&gt;&lt;p&gt;لحذف مقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);

$article-&amp;gt;delete();
&lt;/pre&gt;&lt;p&gt;أو يمكنك حذف سجل مباشرة بواسطة ID:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::destroy(1);
&lt;/pre&gt;&lt;p&gt;ويمكن أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::destroy([1, 2, 3]);
&lt;/pre&gt;&lt;p&gt;لحذف عدة سجلات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الحذف باستخدام Query&lt;/h3&gt;&lt;p&gt;يمكن حذف مجموعة من السجلات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::where('is_published', false)-&amp;gt;delete();
&lt;/pre&gt;&lt;p&gt;لكن يجب الانتباه إلى أن عمليات الحذف الجماعي بهذه الطريقة لا تقوم بتحميل كل Model بشكل منفصل، وبالتالي لا يتم إطلاق أحداث Model لكل سجل كما يحدث عند حذف Models فردية.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Soft Deletes&lt;/h3&gt;&lt;p&gt;في بعض التطبيقات لا نريد حذف البيانات فعليًا.&lt;/p&gt;&lt;p&gt;مثلًا إذا قام مدير الموقع بحذف مقال، قد نريد الاحتفاظ به في قاعدة البيانات حتى يمكن استعادته لاحقًا.&lt;/p&gt;&lt;p&gt;هنا يمكن استخدام:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Soft Deletes&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;بدل حذف السجل فعليًا، يتم تسجيل وقت الحذف في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;deleted_at
&lt;/pre&gt;&lt;p&gt;ولتمكين ذلك نستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Database\Eloquent\SoftDeletes;

class Article extends Model
{
    use SoftDeletes;
}
&lt;/pre&gt;&lt;p&gt;ويجب أيضًا أن يحتوي الجدول على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;softDeletes();
&lt;/pre&gt;&lt;p&gt;عند استخدام Soft Deletes، يتم استبعاد السجلات المحذوفة مؤقتًا من الاستعلامات العادية، بينما تبقى البيانات في قاعدة البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;مثال عملي كامل على Article Model&lt;/h3&gt;&lt;p&gt;لننشئ Model لمقالات موقعنا.&lt;/p&gt;&lt;p&gt;يمكن أن يكون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

namespace App\Models;

use Illuminate\Database\Eloquent\Attributes\Fillable;
use Illuminate\Database\Eloquent\Model;

#[Fillable([
    'title',
    'slug',
    'excerpt',
    'content',
    'is_published',
])]
class Article extends Model
{
    //
}
&lt;/pre&gt;&lt;p&gt;لدينا الآن Model يمثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;ويسمح بالتعبئة الجماعية للحقول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
slug
excerpt
content
is_published
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;استخدام Model داخل Controller&lt;/h3&gt;&lt;p&gt;لنفرض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;ArticleController
&lt;/pre&gt;&lt;p&gt;ونريد عرض جميع المقالات.&lt;/p&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Models\Article;

public function index()
{
    $articles = Article::latest()-&amp;gt;get();

    return view('articles.index', compact('articles'));
}
&lt;/pre&gt;&lt;p&gt;هنا حدثت عدة خطوات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Controller
   ↓
Article Model
   ↓
Database
   ↓
articles
   ↓
Collection
   ↓
Blade View
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;عرض المقالات داخل Blade&lt;/h3&gt;&lt;p&gt;في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;resources/views/articles/index.blade.php
&lt;/pre&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;h1&amp;gt;المقالات&amp;lt;/h1&amp;gt;

@foreach ($articles as $article)
    &amp;lt;article&amp;gt;
        &amp;lt;h2&amp;gt;{{ $article-&amp;gt;title }}&amp;lt;/h2&amp;gt;

        &amp;lt;p&amp;gt;
            {{ $article-&amp;gt;excerpt }}
        &amp;lt;/p&amp;gt;

        &amp;lt;a href="{{ route('articles.show', $article) }}"&amp;gt;
            اقرأ المقال
        &amp;lt;/a&amp;gt;
    &amp;lt;/article&amp;gt;
@endforeach
&lt;/pre&gt;&lt;p&gt;لاحظ كيف أصبح لدينا الآن تدفق كامل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route
 ↓
Controller
 ↓
Model
 ↓
Database
 ↓
Controller
 ↓
View
&lt;/pre&gt;&lt;p&gt;وهذا هو الاستخدام الحقيقي لـ Laravel.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استقبال البيانات من Form وحفظها&lt;/h3&gt;&lt;p&gt;في الدرس السابع تعلمنا Validation.&lt;/p&gt;&lt;p&gt;يمكن الآن دمج Validation مع Eloquent.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'title' =&amp;gt; ['required', 'string', 'max:255'],
        'slug' =&amp;gt; ['required', 'string', 'max:255'],
        'content' =&amp;gt; ['required', 'string'],
    ]);

    Article::create($validated);

    return redirect()
        -&amp;gt;route('articles.index')
        -&amp;gt;with('success', 'تم إنشاء المقال بنجاح.');
}
&lt;/pre&gt;&lt;p&gt;هنا لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Form
 ↓
Request
 ↓
Validation
 ↓
validated()
 ↓
Article::create()
 ↓
Database
&lt;/pre&gt;&lt;p&gt;وهذه واحدة من أهم التدفقات التي ستستخدمها باستمرار في Laravel.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نستخدم validated()؟&lt;/h3&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create($request-&amp;gt;all());
&lt;/pre&gt;&lt;p&gt;نستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'title' =&amp;gt; ['required', 'string'],
    'content' =&amp;gt; ['required', 'string'],
]);

Article::create($validated);
&lt;/pre&gt;&lt;p&gt;والسبب أن البيانات التي تمر إلى Model هي البيانات التي اجتازت Validation فقط.&lt;/p&gt;&lt;p&gt;وهذا يجعل الكود أكثر وضوحًا وأمانًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التعامل مع Query Builder داخل Eloquent&lt;/h3&gt;&lt;p&gt;Eloquent لا يمنعك من استخدام طرق الاستعلام المختلفة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('is_published', true)
    -&amp;gt;orderBy('created_at', 'desc')
    -&amp;gt;limit(10)
    -&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;يمكنك بناء الاستعلام خطوة بخطوة.&lt;/p&gt;&lt;p&gt;فكرة Eloquent الأساسية أن Model يعمل أيضًا كواجهة Query Builder، ولذلك يمكنك إضافة شروط وترتيب وحدود ثم استخدام &lt;code inline=""&gt;get()&lt;/code&gt; للحصول على النتائج.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الفرق بين get() وfirst()&lt;/h3&gt;&lt;p&gt;من الأخطاء الشائعة الخلط بين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;get()
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;first()
&lt;/pre&gt;&lt;h3&gt;get()&lt;/h3&gt;&lt;p&gt;تعيد مجموعة من النتائج:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::where('is_published', true)-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;النتيجة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Collection
&lt;/pre&gt;&lt;h3&gt;first()&lt;/h3&gt;&lt;p&gt;تعيد Model واحدًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::where('slug', $slug)-&amp;gt;first();
&lt;/pre&gt;&lt;p&gt;النتيجة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article Model
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;null
&lt;/pre&gt;&lt;p&gt;إذا لم يوجد شيء.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الفرق بين find() وwhere()&lt;/h3&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::find(5);
&lt;/pre&gt;&lt;p&gt;عندما تعرف الـ Primary Key.&lt;/p&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::where('slug', 'learn-laravel')-&amp;gt;first();
&lt;/pre&gt;&lt;p&gt;فهي مناسبة عندما تريد البحث باستخدام عمود آخر.&lt;/p&gt;&lt;p&gt;بشكل مبسط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;find()
 ↓
Primary Key

where()
 ↓
أي شرط مناسب
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;التعامل مع البيانات الكبيرة&lt;/h3&gt;&lt;p&gt;إذا كان جدولك يحتوي على آلاف أو عشرات الآلاف من السجلات، لا يكون من المناسب دائمًا تحميلها كلها باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::all();
&lt;/pre&gt;&lt;p&gt;دفعة واحدة.&lt;/p&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::chunk(200, function ($articles) {
    foreach ($articles as $article) {
        // معالجة المقال
    }
});
&lt;/pre&gt;&lt;p&gt;يقوم &lt;code inline=""&gt;chunk()&lt;/code&gt; بمعالجة البيانات على دفعات، مما يقلل استهلاك الذاكرة عند التعامل مع أعداد كبيرة من السجلات.&lt;/p&gt;&lt;p&gt;وهذا موضوع مهم عندما تبدأ ببناء تطبيقات تحتوي على بيانات كبيرة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;CRUD كامل للمقالات&lt;/h3&gt;&lt;p&gt;أصبح بإمكاننا الآن تصور CRUD كامل.&lt;/p&gt;&lt;p&gt;CRUD تعني:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Create
Read
Update
Delete
&lt;/pre&gt;&lt;p&gt;أي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إنشاء
قراءة
تعديل
حذف
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #274e13;"&gt;Create&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create([
    'title' =&amp;gt; 'Laravel',
    'slug' =&amp;gt; 'laravel',
    'content' =&amp;gt; 'تعلم Laravel',
]);
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #274e13;"&gt;Read&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::all();
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #274e13;"&gt;Update&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::findOrFail(1);

$article-&amp;gt;update([
    'title' =&amp;gt; 'Laravel للمبتدئين',
]);
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #274e13;"&gt;Delete&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::findOrFail(1);

$article-&amp;gt;delete();
&lt;/pre&gt;&lt;p&gt;بهذه العمليات الأربع يمكنك بناء الأساس لمعظم أنظمة إدارة البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;مثال على دورة CRUD داخل Laravel&lt;/h3&gt;&lt;p&gt;لنفترض أن المستخدم يريد إضافة مقال.&lt;/p&gt;&lt;p&gt;يحدث الآتي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;المستخدم
   ↓
Form
   ↓
POST /articles
   ↓
Route
   ↓
ArticleController@store
   ↓
Validation
   ↓
Article Model
   ↓
Database
   ↓
Redirect
&lt;/pre&gt;&lt;p&gt;وعندما يريد عرض المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;GET /articles/1
   ↓
Route
   ↓
Controller
   ↓
Article::findOrFail(1)
   ↓
View
   ↓
HTML
&lt;/pre&gt;&lt;p&gt;وعندما يريد تعديله:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Form
 ↓
PUT /articles/1
 ↓
Controller
 ↓
Validation
 ↓
Article
 ↓
update()
 ↓
Database
&lt;/pre&gt;&lt;p&gt;وعندما يريد حذفه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DELETE /articles/1
 ↓
Controller
 ↓
Article
 ↓
delete()
 ↓
Database
&lt;/pre&gt;&lt;p&gt;وهنا تبدأ الصورة الكبيرة لـ Laravel في الظهور.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أخطاء شائعة عند استخدام Eloquent&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;1 - نسيان إنشاء Migration&lt;/b&gt;&lt;/p&gt;&lt;p&gt;وجود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article.php
&lt;/pre&gt;&lt;p&gt;لا يعني أن جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;موجود.&lt;/p&gt;&lt;p&gt;يجب أن تكون قد أنشأت Migration وشغلت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;2 - اسم الجدول لا يتوافق مع Model&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان لديك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;يتوقع Eloquent:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;إذا كان جدولك باسم مختلف، يجب تعريفه بشكل صريح.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;3 - استخدام create() بدون Fillable&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كتبت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create($data);
&lt;/pre&gt;&lt;p&gt;يجب ضبط Mass Assignment protection باستخدام &lt;code inline=""&gt;Fillable&lt;/code&gt; أو الآلية المناسبة في Model. Laravel يحمي Models افتراضيًا من Mass Assignment غير المسموح به.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;4 - استخدام all() مع جدول ضخم&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لا تستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::all();
&lt;/pre&gt;&lt;p&gt;بشكل عشوائي على جداول ضخمة إذا كنت لا تحتاج كل السجلات.&lt;/p&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;paginate()
chunk()
lazy()
cursor()
&lt;/pre&gt;&lt;p&gt;بحسب السيناريو.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;5 - عدم استخدام findOrFail() عند الحاجة إلى 404&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان الهدف صفحة تفاصيل مقال، يمكن أن يكون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::findOrFail($id);
&lt;/pre&gt;&lt;p&gt;أفضل من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::find($id);
&lt;/pre&gt;&lt;p&gt;إذا كان عدم وجود المقال يجب أن يؤدي إلى 404.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أفضل ممارسات استخدام Eloquent&lt;/h3&gt;&lt;h3&gt;استخدم Models بدل وضع SQL في كل مكان&lt;/h3&gt;&lt;p&gt;اجعل التعامل مع البيانات منظمًا داخل Models وطبقات التطبيق المناسبة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;1 - استخدم أسماء واضحة&lt;/b&gt;&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
Category
Comment
User
&lt;/pre&gt;&lt;p&gt;بدل أسماء غامضة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;2 -استخدم Validation قبل الحفظ&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لا تحفظ بيانات Form مباشرة قبل التحقق منها.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;3 - لا تمرر Request بالكامل إلى create()&lt;/b&gt;&lt;/p&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;gt;Article::create($request-&amp;gt;all());
&lt;/pre&gt;&lt;p&gt;استخدم البيانات التي تم التحقق منها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create($validated);
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;4 - استخدم Mass Assignment protection&lt;/b&gt;&lt;/p&gt;&lt;p&gt;حدد الحقول التي يسمح للتطبيق بتعبئتها.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;5 - لا تحمل بيانات أكثر مما تحتاج&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان هدفك التعامل مع عدد محدود من السجلات، استخدم شروطًا وحدودًا مناسبة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;span style="color: #660000;"&gt;&lt;b&gt;تمرين عملي&lt;/b&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;الآن جاء دورك.&lt;/p&gt;&lt;p&gt;أنشئ Model باسم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article -m
&lt;/pre&gt;&lt;p&gt;ثم تأكد من وجود Migration لجدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;واجعله يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
title
slug
excerpt
content
is_published
created_at
updated_at
&lt;/pre&gt;&lt;p&gt;ثم شغّل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;بعد ذلك قم بإعداد Model للسماح بالحقول المناسبة لـ Mass Assignment.&lt;/p&gt;&lt;p&gt;ثم جرّب في Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::create([
    'title' =&amp;gt; 'أول مقال في Laravel',
    'slug' =&amp;gt; 'first-laravel-article',
    'excerpt' =&amp;gt; 'مقال تجريبي',
    'content' =&amp;gt; 'هذا محتوى المقال.',
    'is_published' =&amp;gt; true,
]);
&lt;/pre&gt;&lt;p&gt;بعد ذلك جرّب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$articles = Article::latest()-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::find(1);
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article = Article::findOrFail(1);
&lt;/pre&gt;&lt;p&gt;ثم عدّل المقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;update([
    'title' =&amp;gt; 'عنوان جديد للمقال',
]);
&lt;/pre&gt;&lt;p&gt;وأخيرًا احذفه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;delete();
&lt;/pre&gt;&lt;p&gt;إذا استطعت تنفيذ هذه العمليات، فقد تعلمت الأساس الحقيقي لـ Eloquent وCRUD.&lt;/p&gt;&lt;p&gt;في هذا الدرس تعرفنا على &lt;strong&gt;Models وEloquent ORM&lt;/strong&gt;، وهما من أهم أجزاء Laravel في التعامل مع قاعدة البيانات.&lt;/p&gt;&lt;p&gt;تعلمنا أن Model يمثل جدولًا في قاعدة البيانات، وأن Model مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;يرتبط افتراضيًا بجدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;وتعلمنا إنشاء Model باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article
&lt;/pre&gt;&lt;p&gt;وإنشاء Model مع Migration باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:model Article -m
&lt;/pre&gt;&lt;p&gt;ثم تعلمنا قراءة البيانات باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::all();
Article::find(1);
Article::findOrFail(1);
Article::first();
Article::where(...)-&amp;gt;get();
&lt;/pre&gt;&lt;p&gt;وتعلمنا ترتيب النتائج باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;latest()
orderBy()
&lt;/pre&gt;&lt;p&gt;والحصول على عدد النتائج باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;count()
&lt;/pre&gt;&lt;p&gt;ثم تعلمنا إنشاء البيانات باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;save()
create()
&lt;/pre&gt;&lt;p&gt;وتحديثها باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;save()
update()
updateOrCreate()
&lt;/pre&gt;&lt;p&gt;وحذفها باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;delete()
destroy()
&lt;/pre&gt;&lt;p&gt;وتعرفنا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Mass Assignment
Fillable
Soft Deletes
Collections
Chunking
&lt;/pre&gt;&lt;p&gt;كما رأينا كيف يمكن دمج:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Requests
Validation
Controllers
Models
Database
Views
&lt;/pre&gt;&lt;p&gt;في دورة واحدة متكاملة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;العلاقة بين الدروس السابقة وهذا الدرس&lt;/h3&gt;&lt;p&gt;حتى الآن أصبح لدينا المسار التالي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Routing
   ↓
Controller
   ↓
Request
   ↓
Validation
   ↓
Model
   ↓
Eloquent
   ↓
Database
   ↓
View
&lt;/pre&gt;&lt;p&gt;وهذا يعني أن البيانات التي يدخلها المستخدم يمكن أن تمر عبر مراحل واضحة ومنظمة قبل أن تصل إلى قاعدة البيانات.&lt;/p&gt;&lt;p&gt;مثلًا عند إنشاء مقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Blade Form
   ↓
POST Request
   ↓
Controller
   ↓
Validation
   ↓
Article Model
   ↓
Eloquent
   ↓
articles Table
&lt;/pre&gt;&lt;p&gt;وهذه هي الطريقة التي يبدأ بها تطبيق Laravel الحقيقي في أخذ شكل واضح ومنظم.&lt;/p&gt;&lt;p&gt;الآن أصبح لدينا:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;Database&lt;/li&gt;&lt;li&gt;Migrations&lt;/li&gt;&lt;li&gt;Models&lt;/li&gt;&lt;li&gt;Eloquent&lt;/li&gt;&lt;li&gt;CRUD&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;لكن هناك سؤال مهم:&lt;/p&gt;&lt;p&gt;ماذا لو كان لدينا أكثر من جدول؟&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
articles
comments
categories
&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;وكيف نربط المقال بالمستخدم؟&lt;/li&gt;&lt;li&gt;وكيف نعرف أن المستخدم لديه عدة مقالات؟&lt;/li&gt;&lt;li&gt;وكيف نربط المقالات بالتصنيفات؟&lt;/li&gt;&lt;li&gt;وكيف نتعامل مع العلاقات بين الجداول؟&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;هنا يأتي الدرس القادم.&lt;/p&gt;&lt;p&gt;في &lt;strong&gt;الدرس العاشر&lt;/strong&gt; سنتعلم:&lt;/p&gt;&lt;pre&gt;&lt;code class="language-text"&gt;Eloquent Relationships
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;وسنشرح بالتفصيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;hasOne
hasMany
belongsTo
belongsToMany
&lt;/pre&gt;&lt;p&gt;وسنتعلم أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Foreign Keys
Pivot Tables
Eager Loading
with()
load()
&lt;/pre&gt;&lt;p&gt;وسنطبق ذلك على مثال حقيقي يربط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;User
 ↓
Articles
 ↓
Comments
&lt;/pre&gt;&lt;p&gt;وبذلك سننتقل من مجرد التعامل مع جدول واحد إلى بناء نظام بيانات مترابط باستخدام Eloquent.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/8683547252748676732/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-models-eloquent.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/8683547252748676732" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/8683547252748676732" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-models-eloquent.html" rel="alternate" title="التعامل مع قاعدة البيانات بسهولة في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvkJ72XA79wfU7GRTG2PMdNPjvtP_AW1YQJw79Cs9E7dSrTqYhVoiag6FftA5MfIa6j5-sapLAe88fLW26ZbL2osjvFC_iJBGyP23TP2rOcYbnv5x8tajD5JLirO7U0aou3YpUaV2ai3wtmzUH9dNI_7WlzQlUS0ObZWfHNfkhOZaI1-0gO_aPJkJngj-G/s72-c/imageedit_3_3884483211.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-6529140786897110141</id><published>2026-09-21T10:24:29.796+03:00</published><updated>2026-09-21T10:24:29.797+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">إنشاء قاعدة البيانات والجداول وإدارتها Database و Migrations في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlgQPHatAcK2GKusj7ck5ddY-y7adUDwP4j7uh_s0eqquQuydlMKO_geS9JtRJOkDKmjWXj6S858uWrHdUN__mEI3koUCpvY7dk17B_xOCY3Y251vpEluDoHE8179sYEZWLMBMZjPJ4Es5Sz57zDUIETM-h0lx8xM8XiUqpiU0zYBUlB6thsKkalrirNgS/s640/imageedit_3_7566869473.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="Database وMigrations في Laravel – إنشاء قاعدة البيانات والجداول وإدارتها" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlgQPHatAcK2GKusj7ck5ddY-y7adUDwP4j7uh_s0eqquQuydlMKO_geS9JtRJOkDKmjWXj6S858uWrHdUN__mEI3koUCpvY7dk17B_xOCY3Y251vpEluDoHE8179sYEZWLMBMZjPJ4Es5Sz57zDUIETM-h0lx8xM8XiUqpiU0zYBUlB6thsKkalrirNgS/s1600/imageedit_3_7566869473.webp" title="Database وMigrations في Laravel – إنشاء قاعدة البيانات والجداول وإدارتها" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;إنشاء قاعدة البيانات والجداول وإدارتها Database وMigrations&lt;/h3&gt;&lt;p&gt;بعد أن تعلّمنا في الدروس السابقة أساسيات Laravel، مثل &lt;a href="https://www.nusurtech.ca/2026/09/laravel-routing.html" target="_blank"&gt;Routing&lt;/a&gt; و &lt;a href="https://www.nusurtech.ca/2026/09/laravel-controllers.html" target="_blank"&gt;Controllers&lt;/a&gt; و &lt;a href="https://www.nusurtech.ca/2026/09/laravel-blade-templates-views.html" target="_blank"&gt;Blade&lt;/a&gt; و Requests وValidation، أصبحنا الآن جاهزين للانتقال إلى جزء مهم جدًا من أي تطبيق ويب: &lt;strong&gt;قاعدة البيانات Database&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;معظم التطبيقات التي نبنيها في Laravel تحتاج إلى تخزين البيانات بشكل دائم. فإذا كنا نبني موقع مقالات، فنحن نحتاج إلى حفظ عناوين المقالات ومحتواها. وإذا كنا نبني متجرًا إلكترونيًا، فنحتاج إلى تخزين المنتجات والعملاء والطلبات. وإذا كنا نبني نظامًا لإدارة المستخدمين، فنحتاج إلى جداول المستخدمين والصلاحيات والبيانات المرتبطة بهم.&lt;/p&gt;&lt;p&gt;وهنا يأتي دور قاعدة البيانات، ثم تأتي &lt;strong&gt;Migrations&lt;/strong&gt; في Laravel لتساعدنا على إنشاء بنية قاعدة البيانات وإدارتها بطريقة منظمة وقابلة للتتبع.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنتعلم كيفية إعداد قاعدة البيانات، وفهم ملف &lt;code inline=""&gt;.env&lt;/code&gt;، وإنشاء الجداول باستخدام Migrations، وتشغيلها والتراجع عنها، بالإضافة إلى التعرف على أهم أنواع الأعمدة والفهارس والمفاتيح الأجنبية، ثم سنبني مثالًا عمليًا لجدول &lt;code inline=""&gt;articles&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هي قاعدة البيانات Database؟&lt;/h3&gt;&lt;p&gt;قاعدة البيانات هي المكان الذي يتم فيه تخزين بيانات التطبيق بطريقة منظمة.&lt;/p&gt;&lt;p&gt;بدلًا من حفظ البيانات داخل ملفات نصية أو متغيرات PHP، يمكننا استخدام نظام متخصص مثل:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;MySQL&lt;/li&gt;&lt;li&gt;MariaDB&lt;/li&gt;&lt;li&gt;PostgreSQL&lt;/li&gt;&lt;li&gt;SQLite&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;وغيرها من أنظمة قواعد البيانات التي يدعمها Laravel.&lt;/p&gt;&lt;p&gt;على سبيل المثال، إذا كان لدينا موقع مقالات، يمكن أن يكون لدينا جدول باسم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;ويحتوي الجدول على أعمدة مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
title
slug
content
status
created_at
updated_at
&lt;/pre&gt;
&lt;p&gt;وبذلك يمكن لكل مقال أن يكون عبارة عن سجل Record داخل هذا الجدول.&lt;/p&gt;&lt;p&gt;الفكرة الأساسية هي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Laravel Application
       ↓
Database Connection
       ↓
Database
       ↓
Tables
       ↓
Rows / Records
&lt;/pre&gt;&lt;p&gt;لكن Laravel لا يجبرك على كتابة SQL يدويًا لإنشاء كل جدول. وهنا تظهر أهمية Migrations.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هي Migrations في Laravel؟&lt;/h3&gt;&lt;p&gt;يمكننا اعتبار Migration بمثابة &lt;strong&gt;نسخة تحكم Version Control لهيكل قاعدة البيانات&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;بدل أن تقول لزميلك:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;أنشئ جدول articles يدويًا، وأضف هذه الأعمدة، ثم أضف هذا المفتاح...&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;يمكنك إنشاء Migration تحتوي على هذه التعليمات، ثم يستطيع أي شخص في المشروع تشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;وسيتم إنشاء الجداول حسب التعريف الموجود في ملفات Migration.&lt;/p&gt;&lt;p&gt;وهذا يجعل قاعدة البيانات جزءًا من كود المشروع ويمكن مشاركتها عبر Git مع بقية ملفات التطبيق.&lt;/p&gt;&lt;p&gt;توثيق Laravel يصف الـ migrations بأنها تشبه نظام Version Control لقاعدة البيانات، لأنها تسمح للفريق بتعريف ومشاركة مخطط قاعدة البيانات وتعديلاته بطريقة منظمة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أين توجد ملفات Migrations؟&lt;/h3&gt;&lt;p&gt;ستجد ملفات Migration داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/migrations
&lt;/pre&gt;&lt;p&gt;وعند فتح المشروع قد تجد ملفات مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/
├── factories/
├── migrations/
│   ├── xxxx_xx_xx_xxxxxx_create_users_table.php
│   ├── xxxx_xx_xx_xxxxxx_create_cache_table.php
│   └── xxxx_xx_xx_xxxxxx_create_jobs_table.php
└── seeders/
&lt;/pre&gt;&lt;p&gt;كل Migration لها اسم يحتوي على Timestamp.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;2026_01_15_120000_create_articles_table.php
&lt;/pre&gt;&lt;p&gt;وجود التاريخ والوقت في اسم الملف يساعد Laravel على معرفة ترتيب تنفيذ الـ migrations.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إعداد قاعدة البيانات في Laravel&lt;/h3&gt;&lt;p&gt;قبل إنشاء الجداول، يجب أن يعرف Laravel قاعدة البيانات التي سيستخدمها التطبيق.&lt;/p&gt;&lt;p&gt;عادة يتم تحديد إعدادات قاعدة البيانات داخل ملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;.env
&lt;/pre&gt;&lt;p&gt;وهذا الملف موجود في جذر مشروع Laravel.&lt;/p&gt;&lt;p&gt;في Laravel الحديث قد يكون المشروع الجديد معدًا افتراضيًا لاستخدام SQLite، ويمكنك استخدام قاعدة بيانات أخرى مثل MySQL أو PostgreSQL إذا كان هذا هو ما تحتاجه. توثيق Laravel 13 يوضح أن إعدادات الاتصال يتم تحديدها من خلال متغيرات البيئة في &lt;code inline=""&gt;.env&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام SQLite&lt;/h3&gt;&lt;p&gt;SQLite خيار بسيط جدًا للمشاريع التعليمية والتجارب المحلية.&lt;/p&gt;&lt;p&gt;في مشروع Laravel يمكن أن يكون الاتصال مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DB_CONNECTION=sqlite
&lt;/pre&gt;&lt;p&gt;وفي هذه الحالة يستخدم Laravel ملف قاعدة بيانات SQLite داخل المشروع.&lt;/p&gt;&lt;p&gt;في المشاريع الجديدة، يمكن أن ينشئ Laravel ملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/database.sqlite
&lt;/pre&gt;&lt;p&gt;بحسب طريقة إنشاء المشروع وإعداداته.&lt;/p&gt;&lt;p&gt;ميزة SQLite أنه لا يحتاج إلى تشغيل خادم MySQL منفصل، ولذلك هو مناسب جدًا عندما تتعلم Laravel أو تبني مشروعًا صغيرًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام MySQL&lt;/h3&gt;&lt;p&gt;إذا أردت استخدام MySQL، يمكن أن تكون إعدادات &lt;code inline=""&gt;.env&lt;/code&gt; مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
&lt;/pre&gt;&lt;p&gt;يجب أن تتوافق هذه القيم مع إعدادات MySQL الموجودة على جهازك.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DB_DATABASE=laravel
&lt;/pre&gt;&lt;p&gt;تعني أن Laravel سيحاول الاتصال بقاعدة بيانات اسمها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;laravel
&lt;/pre&gt;&lt;p&gt;ويجب أن تكون قاعدة البيانات موجودة بالفعل في MySQL.&lt;/p&gt;&lt;p&gt;بعد إعداد الاتصال، يمكنك تشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;لتنفيذ الـ migrations وإنشاء الجداول.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نستخدم ملف .env؟&lt;/h3&gt;&lt;p&gt;من الأخطاء الشائعة أن تضع بيانات الاتصال بقاعدة البيانات مباشرة داخل ملفات المشروع.&lt;/p&gt;&lt;p&gt;مثلًا لا يُفضل أن تكتب كلمة المرور داخل Controller:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;gt;$password = 'mypassword';
&lt;/pre&gt;&lt;p&gt;بدلًا من ذلك تستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DB_PASSWORD=mypassword
&lt;/pre&gt;&lt;p&gt;ثم يعتمد Laravel على إعدادات البيئة.&lt;/p&gt;&lt;p&gt;وهذا مفيد لأن إعدادات جهاز المطور قد تختلف عن إعدادات السيرفر.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Developer Machine
DB_DATABASE=laravel_dev

Testing Server
DB_DATABASE=laravel_testing

Production Server
DB_DATABASE=laravel_production
&lt;/pre&gt;&lt;p&gt;وبذلك لا تحتاج إلى تغيير كود التطبيق نفسه عند تغيير البيئة.&lt;/p&gt;&lt;p&gt;كما أن ملف &lt;code inline=""&gt;.env&lt;/code&gt; قد يحتوي على بيانات حساسة، ولذلك يجب عدم رفعه إلى مستودع Git العام. توثيق Laravel يحذر من وضع &lt;code inline=""&gt;.env&lt;/code&gt; في Source Control لأن ذلك قد يؤدي إلى كشف بيانات حساسة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء أول Migration&lt;/h3&gt;&lt;p&gt;لنفرض أننا نريد إنشاء جدول للمقالات.&lt;/p&gt;&lt;p&gt;يمكننا تنفيذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration create_articles_table
&lt;/pre&gt;&lt;p&gt;سيقوم Laravel بإنشاء ملف جديد داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/migrations
&lt;/pre&gt;&lt;p&gt;وسيكون الاسم شبيهًا بـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;2026_09_17_120000_create_articles_table.php
&lt;/pre&gt;&lt;p&gt;التاريخ والوقت في الاسم يختلفان حسب وقت إنشاء الملف.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;فهم ملف Migration&lt;/h3&gt;&lt;p&gt;عند فتح Migration ستجد بنية مشابهة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        //
    }

    public function down(): void
    {
        //
    }
};
&lt;/pre&gt;&lt;p&gt;لدينا هنا وظيفتان أساسيتان:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;up()
&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;down()
&lt;/pre&gt;
&lt;h3 style="text-align: right;"&gt;ما وظيفة up()؟&lt;/h3&gt;&lt;p&gt;الدالة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;up()
&lt;/pre&gt;&lt;p&gt;تحتوي على التغييرات التي نريد تطبيقها على قاعدة البيانات.&lt;/p&gt;&lt;p&gt;مثلًا إنشاء جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table-&amp;gt;id();
        $table-&amp;gt;string('title');
        $table-&amp;gt;text('content');
        $table-&amp;gt;timestamps();
    });
}
&lt;/pre&gt;&lt;p&gt;هذا يعني أننا نريد إنشاء جدول اسمه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;وإضافة مجموعة من الأعمدة إليه.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما وظيفة down()؟&lt;/h3&gt;&lt;p&gt;الدالة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;down()
&lt;/pre&gt;&lt;p&gt;تحتوي على العملية العكسية.&lt;/p&gt;&lt;p&gt;إذا أنشأنا جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;في &lt;code inline=""&gt;up()&lt;/code&gt;، فمن الطبيعي أن تقوم &lt;code inline=""&gt;down()&lt;/code&gt; بحذفه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function down(): void
{
    Schema::dropIfExists('articles');
}
&lt;/pre&gt;&lt;p&gt;وبذلك يستطيع Laravel التراجع عن Migration عند استخدام أوامر الـ rollback.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء جدول Articles كامل&lt;/h3&gt;&lt;p&gt;لننشئ جدولًا بسيطًا للمقالات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table-&amp;gt;id();
        $table-&amp;gt;string('title');
        $table-&amp;gt;string('slug')-&amp;gt;unique();
        $table-&amp;gt;text('content');
        $table-&amp;gt;boolean('is_published')-&amp;gt;default(false);
        $table-&amp;gt;timestamps();
    });
}
&lt;/pre&gt;&lt;p&gt;والـ &lt;code inline=""&gt;down()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function down(): void
{
    Schema::dropIfExists('articles');
}
&lt;/pre&gt;&lt;p&gt;الآن أصبح لدينا جدول يمكن استخدامه لتخزين المقالات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;فهم $table-&amp;gt;id()&lt;/h3&gt;&lt;p&gt;السطر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;id();
&lt;/pre&gt;&lt;p&gt;ينشئ عمودًا يسمى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
&lt;/pre&gt;&lt;p&gt;ويستخدم عادة كمفتاح أساسي Primary Key للجدول.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
1
2
3
4
&lt;/pre&gt;&lt;p&gt;كل مقال يمكن أن يكون له ID مختلف.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء أعمدة نصية&lt;/h3&gt;&lt;p&gt;لإنشاء عمود نصي قصير:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('title');
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Laravel للمبتدئين
&lt;/pre&gt;&lt;p&gt;ويمكن تحديد طول العمود عند الحاجة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('title', 150);
&lt;/pre&gt;&lt;p&gt;لكن في كثير من الحالات يكفي استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('title');
&lt;/pre&gt;
&lt;h3 style="text-align: right;"&gt;استخدام text()&lt;/h3&gt;&lt;p&gt;إذا كان لدينا نص طويل مثل محتوى المقال، يمكن استخدام:&lt;/p&gt;
&lt;pre&gt;$table-&amp;gt;text('content');
&lt;/pre&gt;&lt;p&gt;وهذا مناسب للمحتوى الأطول من البيانات النصية القصيرة.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;text('description');
$table-&amp;gt;text('content');
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;الأرقام&lt;/h3&gt;&lt;p&gt;يمكن أن نحتاج إلى تخزين أرقام.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;integer('views');
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;unsignedInteger('views');
&lt;/pre&gt;&lt;p&gt;ويمكن أيضًا استخدام أنواع أخرى حسب الحاجة مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;bigInteger('number');
&lt;/pre&gt;&lt;p&gt;لكن اختيار نوع العمود يجب أن يعتمد على طبيعة البيانات التي ستخزنها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Boolean&lt;/h3&gt;&lt;p&gt;إذا كانت لدينا قيمة نعم/لا، يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;boolean('is_published');
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;true
false
&lt;/pre&gt;&lt;p&gt;ويمكن إعطاؤها قيمة افتراضية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;boolean('is_published')-&amp;gt;default(false);
&lt;/pre&gt;&lt;p&gt;وهذا يعني أن المقال الجديد سيكون غير منشور افتراضيًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التاريخ والوقت&lt;/h3&gt;&lt;p&gt;يمكن إنشاء أعمدة للتاريخ والوقت باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;date('published_at');
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;dateTime('published_at');
&lt;/pre&gt;&lt;p&gt;والفرق أن &lt;code inline=""&gt;date&lt;/code&gt; يخزن التاريخ، بينما &lt;code inline=""&gt;dateTime&lt;/code&gt; يخزن التاريخ والوقت.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;timestamps()&lt;/h3&gt;&lt;p&gt;من أكثر الأسطر استخدامًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;timestamps();
&lt;/pre&gt;&lt;p&gt;وهو يضيف عمودين:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;created_at
updated_at
&lt;/pre&gt;&lt;p&gt;الأول يحدد وقت إنشاء السجل.&lt;/p&gt;&lt;p&gt;والثاني يحدد وقت آخر تعديل عليه.&lt;/p&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id | title              | created_at          | updated_at
1  | تعلم Laravel       | 2026-09-17 ...      | 2026-09-17 ...
&lt;/pre&gt;&lt;p&gt;وهذان العمودان مهمان جدًا في تطبيقات Laravel.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;nullable()&lt;/h3&gt;&lt;p&gt;أحيانًا يكون لدينا عمود اختياري.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('subtitle')-&amp;gt;nullable();
&lt;/pre&gt;&lt;p&gt;هذا يعني أن &lt;code inline=""&gt;subtitle&lt;/code&gt; يمكن أن تكون قيمته:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;NULL
&lt;/pre&gt;&lt;p&gt;بدل أن تكون مطلوبة دائمًا.&lt;/p&gt;&lt;p&gt;مثال عملي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('title');
$table-&amp;gt;string('subtitle')-&amp;gt;nullable();
&lt;/pre&gt;&lt;p&gt;هنا:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;code inline=""&gt;title&lt;/code&gt; مطلوب.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;code inline=""&gt;subtitle&lt;/code&gt; اختياري.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;وهذا يتوافق أيضًا مع مفهوم &lt;code inline=""&gt;nullable&lt;/code&gt; الذي تعرفنا عليه في درس Validation، لكن يجب الانتباه إلى أن &lt;code inline=""&gt;nullable&lt;/code&gt; في قاعدة البيانات يتعلق بالسماح بتخزين &lt;code inline=""&gt;NULL&lt;/code&gt;، بينما قاعدة &lt;code inline=""&gt;nullable&lt;/code&gt; في Validation تتعلق بكيفية التحقق من البيانات القادمة إلى التطبيق.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;default()&lt;/h3&gt;&lt;p&gt;يمكننا إعطاء العمود قيمة افتراضية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;boolean('is_published')-&amp;gt;default(false);
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;integer('views')-&amp;gt;default(0);
&lt;/pre&gt;&lt;p&gt;إذا أنشأنا سجلًا ولم نرسل قيمة &lt;code inline=""&gt;views&lt;/code&gt;، يمكن أن تكون القيمة الافتراضية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;0
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;unique()&lt;/h3&gt;&lt;p&gt;إذا أردنا منع تكرار قيمة معينة، يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('slug')-&amp;gt;unique();
&lt;/pre&gt;&lt;p&gt;هذا مهم جدًا في المقالات.&lt;/p&gt;&lt;p&gt;فإذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;laravel-routing
&lt;/pre&gt;&lt;p&gt;لا نريد أن يكون هناك مقالان بنفس الـ slug.&lt;/p&gt;&lt;p&gt;وبذلك تصبح قيمة &lt;code inline=""&gt;slug&lt;/code&gt; فريدة داخل الجدول.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هي Indexes؟&lt;/h3&gt;&lt;p&gt;الـ Index هو فهرس يساعد قاعدة البيانات على البحث والتعامل مع البيانات بكفاءة في حالات معينة.&lt;/p&gt;&lt;p&gt;يمكن إنشاء Index مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;index('status');
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;index(['status', 'created_at']);
&lt;/pre&gt;&lt;p&gt;ليس معنى ذلك أن علينا إضافة Index إلى كل عمود.&lt;/p&gt;&lt;p&gt;يجب استخدام الفهارس بناءً على احتياجات التطبيق والاستعلامات التي يتم تنفيذها بشكل متكرر.&lt;/p&gt;&lt;p&gt;مثلًا إذا كان التطبيق يبحث كثيرًا عن المقالات حسب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;status
&lt;/pre&gt;&lt;p&gt;فقد يكون من المفيد إنشاء Index لهذا العمود.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Foreign Keys والمفاتيح الأجنبية&lt;/h3&gt;&lt;p&gt;في التطبيقات الحقيقية، غالبًا لا تكون الجداول منفصلة عن بعضها.&lt;/p&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users
articles
&lt;/pre&gt;&lt;p&gt;وكل مقال ينتمي إلى مستخدم.&lt;/p&gt;&lt;p&gt;يمكن أن يحتوي جدول &lt;code inline=""&gt;articles&lt;/code&gt; على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;user_id
&lt;/pre&gt;&lt;p&gt;وهذا العمود يمكن أن يرتبط بـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;users.id
&lt;/pre&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;foreignId('user_id')-&amp;gt;constrained();
&lt;/pre&gt;&lt;p&gt;وهنا نخبر قاعدة البيانات بأن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.user_id
&lt;/pre&gt;&lt;p&gt;مرتبط بمفتاح في جدول المستخدمين.&lt;/p&gt;&lt;p&gt;يمكن أيضًا تحديد ما يحدث عند حذف المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;foreignId('user_id')
    -&amp;gt;constrained()
    -&amp;gt;cascadeOnDelete();
&lt;/pre&gt;&lt;p&gt;وبهذا يمكن إعداد علاقة في قاعدة البيانات بحيث يؤدي حذف المستخدم إلى حذف السجلات المرتبطة به وفق هذا القيد.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;مثال عملي: Articles مع Users&lt;/h3&gt;&lt;p&gt;يمكن أن يكون Migration للمقالات مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function up(): void
{
    Schema::create('articles', function (Blueprint $table) {
        $table-&amp;gt;id();

        $table-&amp;gt;foreignId('user_id')
            -&amp;gt;constrained()
            -&amp;gt;cascadeOnDelete();

        $table-&amp;gt;string('title');
        $table-&amp;gt;string('slug')-&amp;gt;unique();
        $table-&amp;gt;text('content');
        $table-&amp;gt;boolean('is_published')-&amp;gt;default(false);
        $table-&amp;gt;timestamp('published_at')-&amp;gt;nullable();

        $table-&amp;gt;timestamps();
    });
}
&lt;/pre&gt;&lt;p&gt;لدينا الآن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
│
├── id
├── user_id
├── title
├── slug
├── content
├── is_published
├── published_at
├── created_at
└── updated_at
&lt;/pre&gt;&lt;p&gt;والـ &lt;code inline=""&gt;user_id&lt;/code&gt; يربط المقال بالمستخدم.&lt;/p&gt;&lt;p&gt;سنتعمق أكثر في العلاقات بين Models والجداول في درس العلاقات القادم، لكن من المهم أن تفهم الآن أساس فكرة Foreign Key.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تشغيل Migrations&lt;/h3&gt;&lt;p&gt;بعد إنشاء Migration، لن يتم إنشاء الجدول تلقائيًا لمجرد إنشاء الملف.&lt;/p&gt;&lt;p&gt;نحتاج إلى تشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;سيقرأ Laravel الـ migrations التي لم يتم تنفيذها، ثم يقوم بتطبيقها على قاعدة البيانات.&lt;/p&gt;&lt;p&gt;إذا كانت Migration الخاصة بـ &lt;code inline=""&gt;articles&lt;/code&gt; صحيحة، سيظهر الجدول في قاعدة البيانات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;كيف يعرف Laravel ما تم تنفيذه؟&lt;/h3&gt;&lt;p&gt;Laravel يحتفظ بسجل للـ migrations التي تم تنفيذها.&lt;/p&gt;&lt;p&gt;وبذلك عندما تشغل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;مرة أخرى، لا يقوم Laravel بإعادة إنشاء كل الجداول من البداية، بل يعرف ما تم تنفيذه وما لم يتم تنفيذه.&lt;/p&gt;&lt;p&gt;وهذه واحدة من أهم فوائد نظام migrations.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التراجع عن آخر Migration&lt;/h3&gt;&lt;p&gt;إذا أردت التراجع عن آخر مجموعة من الـ migrations التي تم تنفيذها، يمكنك استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:rollback
&lt;/pre&gt;&lt;p&gt;توثيق Laravel يوضح أن &lt;code inline=""&gt;rollback&lt;/code&gt; يتراجع عن آخر Batch من migrations، وقد يحتوي هذا الـ batch على أكثر من ملف Migration.&lt;/p&gt;&lt;p&gt;يمكنك أيضًا تحديد عدد الخطوات:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:rollback --step=1
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:rollback --step=5
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;migrate:reset&lt;/h3&gt;&lt;p&gt;هناك أمر آخر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:reset
&lt;/pre&gt;&lt;p&gt;يؤدي إلى التراجع عن جميع الـ migrations.&lt;/p&gt;&lt;p&gt;هذا يختلف عن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:rollback
&lt;/pre&gt;&lt;p&gt;لأن rollback يتعامل مع آخر Batch، بينما reset يتراجع عن جميع الـ migrations.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;migrate:refresh&lt;/h3&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:refresh
&lt;/pre&gt;&lt;p&gt;وهو يقوم بالتراجع عن الـ migrations ثم تشغيلها من جديد.&lt;/p&gt;&lt;p&gt;أي أن الفكرة بشكل مبسط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Rollback
   ↓
Migrate Again
&lt;/pre&gt;&lt;p&gt;ويمكن تشغيله مع Seeders أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:refresh --seed
&lt;/pre&gt;&lt;p&gt;توثيق Laravel يوضح أن &lt;code inline=""&gt;refresh&lt;/code&gt; يعيد تشغيل migrations بعد التراجع عنها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;migrate:fresh&lt;/h3&gt;&lt;p&gt;من الأوامر المهمة أيضًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh
&lt;/pre&gt;&lt;p&gt;هذا الأمر يقوم بحذف جميع الجداول ثم تشغيل جميع الـ migrations من جديد.&lt;/p&gt;&lt;p&gt;ويمكن تشغيله مع Seeders:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh --seed
&lt;/pre&gt;&lt;p&gt;لكن انتبه جدًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;migrate:fresh
&lt;/pre&gt;&lt;p&gt;يمكن أن يحذف البيانات الموجودة في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;لذلك استخدمه بحذر، وخصوصًا لا تستخدمه على قاعدة بيانات Production بدون فهم كامل لما سيحدث.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الفرق بين أهم أوامر Migrations&lt;/h3&gt;&lt;p&gt;يمكنك حفظ الفرق بهذا الشكل:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;الأمر&lt;/th&gt;&lt;th&gt;الوظيفة&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;php artisan migrate&lt;/code&gt;&lt;/td&gt;&lt;td&gt;تنفيذ الـ migrations الجديدة&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;php artisan migrate:rollback&lt;/code&gt;&lt;/td&gt;&lt;td&gt;التراجع عن آخر Batch&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;php artisan migrate:reset&lt;/code&gt;&lt;/td&gt;&lt;td&gt;التراجع عن جميع الـ migrations&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;php artisan migrate:refresh&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Rollback ثم تشغيل migrations من جديد&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;php artisan migrate:fresh&lt;/code&gt;&lt;/td&gt;&lt;td&gt;حذف الجداول ثم إعادة إنشائها&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;php artisan migrate:fresh --seed&lt;/code&gt;&lt;/td&gt;&lt;td&gt;حذف الجداول وإعادة إنشائها وتشغيل Seeders&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;هذه الأوامر مهمة جدًا أثناء تطوير التطبيقات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;تعديل جدول موجود&lt;/h3&gt;&lt;p&gt;لنفترض أنك أنشأت جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;ثم اكتشفت أنك تحتاج إلى إضافة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;excerpt
&lt;/pre&gt;&lt;p&gt;لا يفضل أن تذهب وتعدل Migration قديمة تم تشغيلها بالفعل على قواعد بيانات الفريق.&lt;/p&gt;&lt;p&gt;بدلًا من ذلك، أنشئ Migration جديدة.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration add_excerpt_to_articles_table
&lt;/pre&gt;&lt;p&gt;ثم داخل Migration:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function up(): void
{
    Schema::table('articles', function (Blueprint $table) {
        $table-&amp;gt;text('excerpt')-&amp;gt;nullable();
    });
}
&lt;/pre&gt;&lt;p&gt;وفي &lt;code inline=""&gt;down()&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function down(): void
{
    Schema::table('articles', function (Blueprint $table) {
        $table-&amp;gt;dropColumn('excerpt');
    });
}
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;وبذلك تمت إضافة العمود إلى الجدول.&lt;/p&gt;&lt;p&gt;هذه الطريقة مهمة جدًا في المشاريع الجماعية؛ لأن كل تغيير في بنية قاعدة البيانات يصبح Migration جديدة يمكن تتبعها ومشاركتها مع الفريق.&lt;/p&gt;&lt;p&gt;وتوصي مواد Laravel التعليمية باستخدام migrations كطريقة منظمة لتغيير بنية قاعدة البيانات بدل تعديل التاريخ القديم عشوائيًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;حذف عمود&lt;/h3&gt;&lt;p&gt;إذا أردت حذف عمود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;dropColumn('excerpt');
&lt;/pre&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Schema::table('articles', function (Blueprint $table) {
    $table-&amp;gt;dropColumn('excerpt');
});
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;إعادة تسمية عمود&lt;/h3&gt;&lt;p&gt;يمكن إعادة تسمية عمود باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;renameColumn('title', 'name');
&lt;/pre&gt;&lt;p&gt;لكن يجب أن تكون حذرًا عند تغيير أسماء الأعمدة في التطبيقات التي تحتوي على كود يعتمد على الاسم القديم.&lt;/p&gt;&lt;p&gt;فإذا كان لديك Controller يستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$article-&amp;gt;title
&lt;/pre&gt;&lt;p&gt;ثم غيرت العمود إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;name
&lt;/pre&gt;&lt;p&gt;ستحتاج أيضًا إلى تحديث الكود الذي يعتمد على &lt;code inline=""&gt;title&lt;/code&gt;.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;حذف جدول&lt;/h3&gt;&lt;p&gt;لحذف جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Schema::dropIfExists('articles');
&lt;/pre&gt;&lt;p&gt;لكن عادة نضع هذا في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;down()
&lt;/pre&gt;&lt;p&gt;حتى يستطيع Laravel التراجع عن Migration.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;مثال عملي كامل&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لنقم الآن ببناء Migration حقيقية لجدول مقالات.&lt;/p&gt;&lt;p&gt;أولًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration create_articles_table
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
    public function up(): void
    {
        Schema::create('articles', function (Blueprint $table) {
            $table-&amp;gt;id();

            $table-&amp;gt;foreignId('user_id')
                -&amp;gt;constrained()
                -&amp;gt;cascadeOnDelete();

            $table-&amp;gt;string('title');
            $table-&amp;gt;string('slug')-&amp;gt;unique();
            $table-&amp;gt;text('excerpt')-&amp;gt;nullable();
            $table-&amp;gt;longText('content');

            $table-&amp;gt;boolean('is_published')
                -&amp;gt;default(false);

            $table-&amp;gt;timestamp('published_at')
                -&amp;gt;nullable();

            $table-&amp;gt;timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('articles');
    }
};
&lt;/pre&gt;&lt;p&gt;بعد ذلك:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;أصبح لدينا جدول مقالات يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
user_id
title
slug
excerpt
content
is_published
published_at
created_at
updated_at
&lt;/pre&gt;&lt;p&gt;وهذا الجدول يمكن أن يكون أساسًا ممتازًا لنظام المقالات الذي سنبنيه تدريجيًا خلال دروس Laravel القادمة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما العلاقة بين Migrations وModels؟&lt;/h3&gt;&lt;p&gt;حتى الآن نحن نتعامل مع بنية قاعدة البيانات.&lt;/p&gt;&lt;p&gt;لكن ماذا لو أردنا داخل Laravel أن نقول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::all();
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article::find(1);
&lt;/pre&gt;&lt;p&gt;هنا ندخل في موضوع مهم جدًا وهو:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Eloquent ORM وModels&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;الـ Migration تحدد لنا شكل الجدول.&lt;/p&gt;&lt;p&gt;أما الـ Model فيمثل البيانات والتعامل معها من داخل التطبيق.&lt;/p&gt;&lt;p&gt;بشكل مبسط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Migration
    ↓
Database Table
    ↓
Model
    ↓
Controller
    ↓
View
&lt;/pre&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;create_articles_table.php
          ↓
      articles
          ↓
       Article
          ↓
 ArticleController
          ↓
   articles/index.blade.php
&lt;/pre&gt;&lt;p&gt;وسنتعلم في الدرس القادم كيف ننشئ Model ونتعامل مع البيانات باستخدام Eloquent.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أخطاء شائعة عند استخدام Migrations&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;تشغيل migrate بدون إعداد قاعدة البيانات&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان لديك MySQL ولم تقم بإنشاء قاعدة البيانات أو كانت بيانات &lt;code inline=""&gt;.env&lt;/code&gt; غير صحيحة، قد تحصل على خطأ في الاتصال.&lt;/p&gt;&lt;p&gt;راجع:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;DB_CONNECTION
DB_HOST
DB_PORT
DB_DATABASE
DB_USERNAME
DB_PASSWORD
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;تعديل Migration قديمة بعد تشغيلها&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كانت Migration قديمة وتم تنفيذها، لا تعتمد على تعديلها فقط وانتظار أن يكتشف Laravel التغيير.&lt;/p&gt;&lt;p&gt;أنشئ Migration جديدة لتعديل الجدول.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;استخدام migrate:fresh بدون الانتباه&lt;/b&gt;&lt;/p&gt;&lt;p&gt;الأمر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:fresh
&lt;/pre&gt;&lt;p&gt;يحذف الجداول ثم يعيد إنشاءها.&lt;/p&gt;&lt;p&gt;لذلك يمكن أن تفقد البيانات الموجودة في قاعدة البيانات. Laravel يحذر من استخدام هذا الأمر بحذر خصوصًا مع قواعد البيانات المشتركة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;نسيان تشغيل migrate&lt;/b&gt;&lt;/p&gt;&lt;p&gt;قد تكتب Migration كاملة ثم تحاول استخدام الجدول، لكنك نسيت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;في هذه الحالة الجدول لن يكون موجودًا في قاعدة البيانات.&lt;/p&gt;&lt;h3&gt;الخلط بين Validation وقاعدة البيانات&lt;/h3&gt;&lt;p&gt;في الدرس السابق استخدمنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    'title' =&amp;gt; ['required', 'string'],
]);
&lt;/pre&gt;&lt;p&gt;هذا يتحقق من البيانات القادمة من المستخدم.&lt;/p&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;string('title');
&lt;/pre&gt;&lt;p&gt;فهذا يحدد شكل العمود في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;إذن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Validation
    ↓
هل البيانات القادمة صحيحة؟

Migration
    ↓
كيف سيكون شكل قاعدة البيانات؟
&lt;/pre&gt;&lt;p&gt;كلاهما مهم، لكن لكل واحد وظيفة مختلفة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أفضل ممارسات Migrations&lt;/h3&gt;&lt;p&gt;عند العمل على مشروع Laravel حقيقي، حاول الالتزام بمجموعة من الممارسات:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;1 - استخدم أسماء واضحة&lt;/b&gt;&lt;/p&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration change_table
&lt;/pre&gt;&lt;p&gt;استخدم اسمًا يوضح ما يحدث:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration add_excerpt_to_articles_table
&lt;/pre&gt;&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration create_articles_table&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;2 - اجعل كل Migration لها هدف واضح&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لا تضع عشرات التغييرات غير المرتبطة في Migration واحدة.&lt;/p&gt;&lt;p&gt;من الأفضل أن تكون كل Migration مسؤولة عن تغيير واضح.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;3 - لا تضع البيانات داخل Migration&lt;/b&gt;&lt;/p&gt;&lt;p&gt;الـ Migration مخصصة بشكل أساسي لبنية قاعدة البيانات.&lt;/p&gt;&lt;p&gt;أما إدخال البيانات التجريبية فيمكن التعامل معه من خلال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Seeders
Factories
&lt;/pre&gt;&lt;p&gt;وسنتعلم ذلك لاحقًا.&lt;/p&gt;&lt;h3&gt;احتفظ بالـ Migrations في Git&lt;/h3&gt;&lt;p&gt;Migration جزء من المشروع، ولذلك يجب أن تكون ضمن ملفات المشروع التي يتم تتبعها في Git.&lt;/p&gt;&lt;p&gt;إذا أضاف أحد أعضاء الفريق Migration جديدة، يمكن لباقي الفريق الحصول عليها وتشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;لتحديث قاعدة البيانات المحلية.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #134f5c;"&gt;تمرين عملي&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;قبل الانتقال إلى الدرس القادم، حاول تنفيذ التمرين التالي بنفسك.&lt;/p&gt;&lt;p&gt;أنشئ Migration باسم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration create_categories_table
&lt;/pre&gt;&lt;p&gt;واجعل جدول &lt;code inline=""&gt;categories&lt;/code&gt; يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
name
slug
description
is_active
created_at
updated_at
&lt;/pre&gt;&lt;p&gt;بحيث:&lt;/p&gt;&lt;code inline=""&gt;&lt;ul&gt;&lt;li&gt;&lt;code inline=""&gt;id&lt;/code&gt; مفتاح أساسي.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;name&lt;/code&gt; نص قصير.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;slug&lt;/code&gt; نص فريد.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;description&lt;/code&gt; نص اختياري.&lt;/li&gt;&lt;li&gt;&lt;code inline=""&gt;is_active&lt;/code&gt; قيمة Boolean.&lt;/li&gt;&lt;li&gt;القيمة الافتراضية لـ &lt;code inline=""&gt;is_active&lt;/code&gt; تكون &lt;code inline=""&gt;true&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;استخدم &lt;code inline=""&gt;timestamps()&lt;/code&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/code&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;p&gt;ثم شغّل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;بعد ذلك جرّب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate:rollback
&lt;/pre&gt;&lt;p&gt;ثم أعد تشغيل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
&lt;/pre&gt;&lt;p&gt;بهذا ستتعرف عمليًا على دورة حياة Migration.&lt;/p&gt;&lt;h4 style="text-align: right;"&gt;ماذا تعلمنا في هذا الدرس؟&lt;/h4&gt;&lt;p&gt;في هذا الدرس تعرفنا على أساسيات قواعد البيانات في Laravel، وتعلمنا أن قاعدة البيانات هي المكان الذي يتم فيه تخزين بيانات التطبيق بشكل دائم.&lt;/p&gt;&lt;p&gt;تعلمنا أيضًا أن Laravel يستخدم ملف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;.env
&lt;/pre&gt;&lt;p&gt;لتحديد إعدادات البيئة، ومنها إعدادات الاتصال بقاعدة البيانات.&lt;/p&gt;&lt;p&gt;ثم تعرفنا على Migrations الموجودة داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;database/migrations
&lt;/pre&gt;&lt;p&gt;وتعلمنا إنشاء Migration باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:migration create_articles_table
&lt;/pre&gt;&lt;p&gt;وتعرفنا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;up()
&lt;/pre&gt;&lt;p&gt;لتطبيق التغيير، و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;down()
&lt;/pre&gt;&lt;p&gt;للتراجع عنه.&lt;/p&gt;&lt;p&gt;كما تعلمنا إنشاء الأعمدة باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$table-&amp;gt;id();
$table-&amp;gt;string();
$table-&amp;gt;text();
$table-&amp;gt;boolean();
$table-&amp;gt;integer();
$table-&amp;gt;timestamp();
$table-&amp;gt;timestamps();
&lt;/pre&gt;&lt;p&gt;وتعرفنا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;nullable()
default()
unique()
index()
foreignId()
constrained()
cascadeOnDelete()
&lt;/pre&gt;&lt;p&gt;ثم تعلمنا أهم أوامر Migration:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan migrate
php artisan migrate:rollback
php artisan migrate:reset
php artisan migrate:refresh
php artisan migrate:fresh
&lt;/pre&gt;&lt;p&gt;وأصبح لدينا الآن تصور واضح عن كيفية بناء هيكل قاعدة البيانات وإدارته داخل Laravel.&lt;/p&gt;&lt;p&gt;الآن أصبح لدينا جدول في قاعدة البيانات، لكننا ما زلنا بحاجة إلى طريقة سهلة للتعامل معه من داخل Laravel.&lt;/p&gt;&lt;p&gt;فبدلًا من كتابة SQL يدويًا في كل مرة نريد فيها قراءة أو إضافة أو تعديل بيانات، يوفر Laravel نظامًا قويًا يسمى:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Eloquent ORM&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;وفي الدرس القادم سنتعلم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Models
Eloquent ORM
Create
Read
Update
Delete
&lt;/pre&gt;&lt;p&gt;وسنبدأ بإنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Article
&lt;/pre&gt;&lt;p&gt;ثم نربطه بجدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles
&lt;/pre&gt;&lt;p&gt;وسنتعلم كيف نضيف المقالات ونقرأها ونعدلها ونحذفها باستخدام Laravel بطريقة سهلة ومنظمة.&lt;/p&gt;&lt;p&gt;وهنا تبدأ قاعدة البيانات بالاندماج فعليًا مع Controllers وValidation وViews التي تعلمناها في الدروس السابقة.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/6529140786897110141/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-database-migrations.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6529140786897110141" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6529140786897110141" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-database-migrations.html" rel="alternate" title="إنشاء قاعدة البيانات والجداول وإدارتها Database و Migrations في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlgQPHatAcK2GKusj7ck5ddY-y7adUDwP4j7uh_s0eqquQuydlMKO_geS9JtRJOkDKmjWXj6S858uWrHdUN__mEI3koUCpvY7dk17B_xOCY3Y251vpEluDoHE8179sYEZWLMBMZjPJ4Es5Sz57zDUIETM-h0lx8xM8XiUqpiU0zYBUlB6thsKkalrirNgS/s72-c/imageedit_3_7566869473.webp" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-5221909926006253414.post-6370452062501607902</id><published>2026-09-20T11:50:58.870+03:00</published><updated>2026-09-20T11:50:58.870+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Laravel"/><title type="text">تمرير البيانات بين Controller و View في Laravel</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvuOYnEUgy8CWXGhTwIJx0V4_GdVtYjCohQ42_Y6In5Dc4ys0R1Qh-j2oYtGLMP30-ntCKig2eB_hyIbpPemaOS__tWL5hyrtwMnJU0wotoG4xYo_Vk8tlEXZCCJbbOtNsPOCbZgvClzxlF2kOUwjse8RV-xo52zKZ6RwmDngXQSd9LhIoFVu4YUsEDpa3/s640/imageedit_1_9071720482.webp" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img alt="تمرير البيانات بين Controller" border="0" data-original-height="380" data-original-width="640" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvuOYnEUgy8CWXGhTwIJx0V4_GdVtYjCohQ42_Y6In5Dc4ys0R1Qh-j2oYtGLMP30-ntCKig2eB_hyIbpPemaOS__tWL5hyrtwMnJU0wotoG4xYo_Vk8tlEXZCCJbbOtNsPOCbZgvClzxlF2kOUwjse8RV-xo52zKZ6RwmDngXQSd9LhIoFVu4YUsEDpa3/s1600/imageedit_1_9071720482.webp" title="تمرير البيانات بين Controller" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;&lt;h3&gt;استقبال البيانات والتحقق منها Requests وValidation في Laravel&lt;/h3&gt;&lt;p&gt;بعد أن تعلمنا في الدرس السادس كيفية استخدام &lt;strong&gt;&lt;a href="https://www.nusurtech.ca/2026/09/laravel-blade-templates-views.html" target="_blank"&gt;Blade Templates&lt;/a&gt; و Views&lt;/strong&gt; لبناء واجهات ديناميكية، أصبح بإمكاننا الآن إنشاء صفحات تحتوي على نصوص وقوائم وأزرار ونماذج Forms.&lt;/p&gt;&lt;p&gt;لكن بناء النموذج وحده لا يكفي.&lt;/p&gt;&lt;p&gt;تخيل أن لدينا نموذجًا لإنشاء مقال يحتوي على:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;عنوان المقال.&lt;/li&gt;&lt;li&gt;محتوى المقال.&lt;/li&gt;&lt;li&gt;البريد الإلكتروني للكاتب.&lt;/li&gt;&lt;li&gt;تاريخ النشر.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;عندما يضغط المستخدم على زر &lt;strong&gt;حفظ&lt;/strong&gt;، يجب أن يستقبل Laravel هذه البيانات، ثم يتأكد من أنها صحيحة قبل أن يستخدمها أو يحفظها في قاعدة البيانات.&lt;/p&gt;&lt;p&gt;هنا يأتي دور &lt;strong&gt;HTTP Request&lt;/strong&gt; و&lt;strong&gt;Validation&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Laravel توفر نظامًا قويًا للتعامل مع البيانات القادمة من المستخدم والتحقق منها باستخدام مجموعة كبيرة من قواعد Validation، كما توفر طريقة أكثر تنظيمًا باستخدام &lt;strong&gt;Form Requests&lt;/strong&gt; عندما تصبح عمليات التحقق أكثر تعقيدًا.&lt;/p&gt;&lt;p&gt;في هذا الدرس سنتعلم :&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;ما هو Request؟&lt;/li&gt;&lt;li&gt;كيف نستقبل البيانات القادمة من Form؟&lt;/li&gt;&lt;li&gt;الفرق بين GET وPOST.&lt;/li&gt;&lt;li&gt;استخدام &lt;code inline=""&gt;Request&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;قراءة بيانات المستخدم.&lt;/li&gt;&lt;li&gt;إنشاء Form باستخدام Blade.&lt;/li&gt;&lt;li&gt;استخدام &lt;code inline=""&gt;@csrf&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;التحقق من البيانات باستخدام &lt;code inline=""&gt;validate()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;أهم قواعد Validation.&lt;/li&gt;&lt;li&gt;عرض رسائل الخطأ.&lt;/li&gt;&lt;li&gt;إعادة تعبئة النموذج بالبيانات القديمة.&lt;/li&gt;&lt;li&gt;استخدام &lt;code inline=""&gt;old()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;إنشاء Form Request.&lt;/li&gt;&lt;li&gt;استخدام &lt;code inline=""&gt;validated()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;التعامل مع الحقول الاختيارية.&lt;/li&gt;&lt;li&gt;بناء نموذج عملي كامل لإنشاء مقال.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو HTTP Request؟&lt;/h3&gt;&lt;p&gt;عندما يفتح المستخدم صفحة في موقعك أو يرسل نموذجًا أو يضغط على زر يؤدي إلى رابط معين، يقوم المتصفح بإرسال &lt;strong&gt;HTTP Request&lt;/strong&gt; إلى الخادم.&lt;/p&gt;&lt;p&gt;مثلًا عندما يفتح المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/articles
&lt;/pre&gt;
&lt;p&gt;قد يكون الطلب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;GET /articles
&lt;/pre&gt;
&lt;p&gt;وعندما يرسل نموذج إنشاء مقال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;POST /articles
&lt;/pre&gt;
&lt;p&gt;يحتوي الطلب على معلومات مختلفة يمكن أن يحتاج إليها التطبيق، مثل:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;البيانات المرسلة من Form.&lt;/li&gt;&lt;li&gt;عنوان الصفحة المطلوبة.&lt;/li&gt;&lt;li&gt;HTTP Method.&lt;/li&gt;&lt;li&gt;Headers.&lt;/li&gt;&lt;li&gt;Cookies.&lt;/li&gt;&lt;li&gt;معلومات أخرى مرتبطة بالطلب.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;في Laravel يمكننا الوصول إلى هذه المعلومات من خلال كائن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Illuminate\Http\Request
&lt;/pre&gt;
&lt;p&gt;وغالبًا نقوم بتمريره إلى Controller Method.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الفرق بين GET و POST في&amp;nbsp;Laravel&lt;/h3&gt;&lt;p&gt;قبل أن نبدأ، من المهم فهم الفرق بين أشهر طريقتين سنستخدمهما في Forms.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #2b00fe;"&gt;GET&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;يستخدم GET عادةً لطلب أو عرض البيانات.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/articles
&lt;/pre&gt;
&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/articles/10
&lt;/pre&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/articles', [ArticleController::class, 'index']);
&lt;/pre&gt;
&lt;p&gt;عندما يزور المستخدم الرابط، يتم إرسال GET Request.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #2b00fe;"&gt;POST&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;يستخدم POST عادةً لإرسال بيانات إلى التطبيق لإنشاء أو معالجة شيء جديد.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::post('/articles', [ArticleController::class, 'store']);
&lt;/pre&gt;
&lt;p&gt;عندما يرسل المستخدم Form إنشاء مقال، يمكن أن تصل البيانات إلى &lt;code inline=""&gt;store()&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;بالتالي يمكن أن تكون الدورة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;GET /articles/create
        ↓
عرض Form
        ↓
المستخدم يملأ البيانات
        ↓
POST /articles
        ↓
Controller
        ↓
Validation
        ↓
حفظ البيانات
&lt;/pre&gt;
&lt;p&gt;Laravel تستخدم هذا النمط بكثرة في تطبيقات CRUD. وتوضح وثائق Validation الرسمية مثالًا مشابهًا يعتمد على Route لعرض النموذج ثم POST Route لمعالجة البيانات والتحقق منها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء Form في Blade&lt;/h3&gt;&lt;p&gt;لنبدأ بإنشاء صفحة تحتوي على نموذج لإضافة مقال.&lt;/p&gt;&lt;p&gt;أنشئ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;resources/views/articles/create.blade.php
&lt;/pre&gt;&lt;p&gt;واكتب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@extends('layouts.app')

@section('title', 'إضافة مقال')

@section('content')

    &amp;lt;h1&amp;gt;إضافة مقال جديد&amp;lt;/h1&amp;gt;

    &amp;lt;form method="POST" action="{{ route('articles.store') }}"&amp;gt;

        @csrf

        &amp;lt;div&amp;gt;
            &amp;lt;label for="title"&amp;gt;عنوان المقال&amp;lt;/label&amp;gt;

            &amp;lt;input
                type="text"
                name="title"
                id="title"
            &amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;div&amp;gt;
            &amp;lt;label for="body"&amp;gt;محتوى المقال&amp;lt;/label&amp;gt;

            &amp;lt;textarea
                name="body"
                id="body"
            &amp;gt;&amp;lt;/textarea&amp;gt;
        &amp;lt;/div&amp;gt;

        &amp;lt;button type="submit"&amp;gt;
            حفظ المقال
        &amp;lt;/button&amp;gt;

    &amp;lt;/form&amp;gt;

@endsection
&lt;/pre&gt;&lt;p&gt;لدينا هنا Form يرسل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
body
&lt;/pre&gt;&lt;p&gt;إلى Route اسمه:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;articles.store
&lt;/pre&gt;
&lt;p&gt;باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;POST
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;ما أهمية&amp;nbsp;@csrf؟&lt;/h3&gt;&lt;p&gt;لاحظ أننا كتبنا داخل Form:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@csrf
&lt;/pre&gt;&lt;p&gt;هذه خطوة مهمة جدًا في Forms التي ترسل طلبات إلى Laravel.&lt;/p&gt;&lt;p&gt;تقوم Laravel باستخدام CSRF Token لحماية التطبيق من نوع من الهجمات يسمى &lt;strong&gt;Cross-Site Request Forgery&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;لذلك عندما تنشئ Form يرسل POST أو PUT أو PATCH أو DELETE إلى تطبيق Laravel، ستحتاج عادةً إلى إضافة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@csrf
&lt;/pre&gt;
&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST" action="/articles"&amp;gt;

    @csrf

    ...
    
&amp;lt;/form&amp;gt;
&lt;/pre&gt;
&lt;p&gt;لا تعتبر &lt;code inline=""&gt;@csrf&lt;/code&gt; مجرد سطر إضافي؛ اجعله عادة أساسية عند إنشاء Forms في Laravel.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء Routes للنموذج&lt;/h3&gt;&lt;p&gt;في:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;routes/web.php
&lt;/pre&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Http\Controllers\ArticleController;

Route::get('/articles/create', [ArticleController::class, 'create'])
    -&amp;gt;name('articles.create');

Route::post('/articles', [ArticleController::class, 'store'])
    -&amp;gt;name('articles.store');
&lt;/pre&gt;&lt;p&gt;الـ Route الأول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;GET /articles/create
&lt;/pre&gt;&lt;p&gt;مسؤول عن عرض Form.&lt;/p&gt;&lt;p&gt;والـ Route الثاني:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;POST /articles
&lt;/pre&gt;&lt;p&gt;مسؤول عن استقبال البيانات.&lt;/p&gt;&lt;p&gt;يمكننا التفكير في الأمر هكذا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;/articles/create
       ↓
     create()
       ↓
     Form
&lt;/pre&gt;
&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Form
  ↓
POST /articles
  ↓
store()
  ↓
Validation
  ↓
حفظ البيانات
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;استقبال البيانات داخل Controller&lt;/h3&gt;&lt;p&gt;افتح:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Http/Controllers/ArticleController.php
&lt;/pre&gt;
&lt;p&gt;ثم أضف:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Http\Request;
&lt;/pre&gt;&lt;p&gt;وبعدها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
{
    //
}
&lt;/pre&gt;&lt;p&gt;الآن Laravel ستمرر Request إلى Method تلقائيًا.&lt;/p&gt;&lt;p&gt;يمكننا قراءة البيانات باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;input('title')
&lt;/pre&gt;
&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
{
    $title = $request-&amp;gt;input('title');

    return $title;
}
&lt;/pre&gt;&lt;p&gt;إذا أرسل المستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;تعلم Laravel
&lt;/pre&gt;&lt;p&gt;ستكون قيمة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$title
&lt;/pre&gt;&lt;p&gt;هي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;تعلم Laravel
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;قراءة أكثر من قيمة&lt;/h3&gt;&lt;p&gt;يمكننا قراءة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;input('title');
&amp;gt;&lt;/pre&gt;&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;input('body');
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
{
    $title = $request-&amp;gt;input('title');
    $body = $request-&amp;gt;input('body');

    return $title;
}
&lt;/pre&gt;&lt;p&gt;لكن هناك مشكلة مهمة:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;هل يمكننا الوثوق بأن البيانات التي أرسلها المستخدم صحيحة؟&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;بالطبع لا.&lt;/p&gt;&lt;p&gt;قد يرسل المستخدم عنوانًا فارغًا.&lt;/p&gt;&lt;p&gt;أو نصًا طويلًا جدًا.&lt;/p&gt;&lt;p&gt;أو قيمة ليست من النوع المطلوب.&lt;/p&gt;&lt;p&gt;أو يترك بعض الحقول فارغة.&lt;/p&gt;&lt;p&gt;وهنا نحتاج إلى Validation.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ما هو Validation؟&lt;/h3&gt;&lt;p&gt;Validation يعني &lt;strong&gt;التحقق من صحة البيانات القادمة إلى التطبيق&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;مثلًا يمكننا تحديد قواعد مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;العنوان مطلوب.
العنوان يجب أن يكون نصًا.
العنوان لا يتجاوز 255 حرفًا.
المحتوى مطلوب.
البريد الإلكتروني يجب أن يكون صالحًا.
السعر يجب أن يكون رقمًا.
&lt;/pre&gt;&lt;p&gt;بدون Validation قد تدخل بيانات غير صحيحة إلى التطبيق وقاعدة البيانات.&lt;/p&gt;&lt;p&gt;Laravel توفر عددًا كبيرًا من Validation Rules الجاهزة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أول Validation باستخدام&amp;nbsp;validate()&lt;/h3&gt;&lt;p&gt;أبسط طريقة هي استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate()
&lt;/pre&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'title' =&amp;gt; ['required', 'string', 'max:255'],
        'body' =&amp;gt; ['required', 'string'],
    ]);

    //
}
&lt;/pre&gt;&lt;p&gt;هنا حددنا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
&lt;/pre&gt;&lt;p&gt;بأنه:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;مطلوب.&lt;/li&gt;&lt;li&gt;نص.&lt;/li&gt;&lt;li&gt;أقصى طول 255.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;body
&lt;/pre&gt;&lt;p&gt;فهو:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;مطلوب.&lt;/li&gt;&lt;li&gt;نص.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;إذا نجحت Validation، يستمر تنفيذ Controller بشكل طبيعي.&lt;/p&gt;&lt;p&gt;أما إذا فشلت، تقوم Laravel بالتعامل مع نتيجة Validation وإعادة المستخدم إلى الصفحة السابقة في الطلبات التقليدية، مع توفير رسائل الأخطاء لعرضها في View.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;فهم قاعدة required في&amp;nbsp;Laravel&lt;/h3&gt;&lt;p&gt;أبسط قاعدة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'required'
&lt;/pre&gt;&lt;p&gt;تعني أن الحقل يجب أن يكون موجودًا وغير فارغ.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required']
&lt;/pre&gt;&lt;p&gt;إذا لم يرسل المستخدم &lt;code inline=""&gt;title&lt;/code&gt; بشكل صحيح، تفشل Validation.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;قاعدة string في&amp;nbsp;Laravel&lt;/h3&gt;&lt;p&gt;يمكنك التأكد من أن القيمة نص باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'string'
&lt;/pre&gt;
&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required', 'string']
&lt;/pre&gt;&lt;p&gt;وهذا مفيد عندما تتوقع قيمة نصية.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;قاعدة max في&amp;nbsp;Laravel&lt;/h3&gt;&lt;p&gt;يمكنك تحديد الحد الأقصى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'max:255'
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required', 'string', 'max:255']
&lt;/pre&gt;&lt;p&gt;وبذلك لا تسمح بعنوان يتجاوز الحد المحدد.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;قاعدة min في&amp;nbsp;Laravel&lt;/h3&gt;&lt;p&gt;يمكنك أيضًا تحديد الحد الأدنى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'min:3'
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required', 'string', 'min:3', 'max:255']
&lt;/pre&gt;&lt;p&gt;وهذا يعني أن العنوان يجب أن يحتوي على عدد مناسب من الأحرف ضمن الحدود المحددة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التحقق من البريد الإلكتروني&lt;/h3&gt;&lt;p&gt;إذا كان لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;email
&lt;/pre&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'email' =&amp;gt; ['required', 'email']
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    'name' =&amp;gt; ['required', 'string'],
    'email' =&amp;gt; ['required', 'email'],
]);
&lt;/pre&gt;&lt;p&gt;Laravel توفر قواعد متخصصة للبريد الإلكتروني، ويمكن أيضًا استخدام خيارات أكثر تقدمًا عندما تحتاج إلى مستوى تحقق إضافي.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التحقق من الأرقام&lt;/h3&gt;&lt;p&gt;إذا كان لدينا سعر:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;price
&lt;/pre&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'price' =&amp;gt; ['required', 'numeric']
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    'name' =&amp;gt; ['required', 'string'],
    'price' =&amp;gt; ['required', 'numeric'],
]);
&lt;/pre&gt;
&lt;p&gt;وهذا مناسب في حالات مثل:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ul style="text-align: right;"&gt;&lt;li&gt;أسعار المنتجات.&lt;/li&gt;&lt;li&gt;الكميات.&lt;/li&gt;&lt;li&gt;التقييمات.&lt;/li&gt;&lt;li&gt;أرقام معينة.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;قاعدة integer في Laravel&lt;/h3&gt;&lt;p&gt;إذا كنت تتوقع رقمًا صحيحًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'quantity' =&amp;gt; ['required', 'integer']
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'quantity' =&amp;gt; ['required', 'integer', 'min:1']
&lt;/pre&gt;
&lt;p&gt;وهذا مناسب عندما تكون القيمة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;1
2
3
4
&lt;/pre&gt;
&lt;p&gt;وليس:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;1.5
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;الحقول الاختيارية باستخدام nullable&lt;/h3&gt;&lt;p&gt;ليس كل حقل يجب أن يكون مطلوبًا.&lt;/p&gt;&lt;p&gt;لنفترض أن لدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;publish_at
&lt;/pre&gt;&lt;p&gt;ويمكن للمستخدم تركه فارغًا.&lt;/p&gt;&lt;p&gt;يمكننا كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'publish_at' =&amp;gt; ['nullable', 'date']
&lt;/pre&gt;&lt;p&gt;أي:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;إذا كانت القيمة موجودة، يجب أن تكون تاريخًا صحيحًا.
أما إذا كانت null فهي مسموحة.
&lt;/pre&gt;&lt;p&gt;وتشير وثائق Laravel 13 إلى أهمية &lt;code inline=""&gt;nullable&lt;/code&gt; عند التعامل مع الحقول الاختيارية التي قد تتحول قيمها الفارغة إلى &lt;code inline=""&gt;null&lt;/code&gt; بسبب Middleware الخاص بالتطبيق.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;عرض رسائل Validation في Blade&lt;/h3&gt;&lt;p&gt;بعد أن وضعنا Validation، نحتاج إلى إظهار الأخطاء للمستخدم.&lt;/p&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@error('title')
    &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
@enderror
&lt;/pre&gt;&lt;p&gt;مثال:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;label for="title"&amp;gt;عنوان المقال&amp;lt;/label&amp;gt;

&amp;lt;input
    type="text"
    name="title"
    id="title"
&amp;gt;

@error('title')
    &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
@enderror
&lt;/pre&gt;&lt;p&gt;إذا كان العنوان غير صالح، يمكن عرض رسالة الخطأ المناسبة.&lt;/p&gt;&lt;p&gt;Laravel توفر أيضًا متغير:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$errors
&lt;/pre&gt;&lt;p&gt;داخل Views للتعامل مع رسائل Validation.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;عرض جميع الأخطاء Laravel&lt;/h3&gt;&lt;p&gt;يمكنك أيضًا عرض جميع الأخطاء في مكان واحد:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@if ($errors-&amp;gt;any())

    &amp;lt;div&amp;gt;
        &amp;lt;ul&amp;gt;

            @foreach ($errors-&amp;gt;all() as $error)

                &amp;lt;li&amp;gt;{{ $error }}&amp;lt;/li&amp;gt;

            @endforeach

        &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;

@endif
&lt;/pre&gt;&lt;p&gt;وهذا مفيد خصوصًا في بداية المشروع أو عندما تريد عرض قائمة عامة بالأخطاء أعلى النموذج.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إعادة البيانات القديمة باستخدام old()&lt;/h3&gt;&lt;p&gt;تخيل أن المستخدم ملأ Form كاملًا ثم نسي عنوان المقال.&lt;/p&gt;&lt;p&gt;ضغط:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;حفظ
&lt;/pre&gt;&lt;p&gt;ففشلت Validation.&lt;/p&gt;&lt;p&gt;من غير الجيد أن تعيد الصفحة فارغة وتجبره على كتابة كل شيء من جديد.&lt;/p&gt;&lt;p&gt;هنا يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;old()
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;input
    type="text"
    name="title"
    value="{{ old('title') }}"
&amp;gt;
&lt;/pre&gt;&lt;p&gt;إذا كان المستخدم كتب:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;تعلم Laravel
&lt;/pre&gt;&lt;p&gt;ثم فشلت Validation بسبب حقل آخر، يمكن إعادة عرض:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;تعلم Laravel
&lt;/pre&gt;&lt;p&gt;داخل الحقل.&lt;/p&gt;&lt;p&gt;وبالنسبة إلى &lt;code inline=""&gt;textarea&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;textarea name="body"&amp;gt;{{ old('body') }}&amp;lt;/textarea&amp;gt;
&lt;/pre&gt;&lt;p&gt;وهذا يجعل تجربة المستخدم أفضل بكثير.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;وضع قيمة افتراضية مع old()&lt;/h3&gt;&lt;p&gt;يمكنك أيضًا توفير قيمة افتراضية:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;{{ old('title', 'عنوان افتراضي') }}
&lt;/pre&gt;&lt;p&gt;إذا لم توجد قيمة قديمة، سيتم استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;عنوان افتراضي
&lt;/pre&gt;
&lt;h3 style="text-align: right;"&gt;مثال كامل على Form مع Validation&lt;/h3&gt;&lt;p&gt;لنقم الآن ببناء Form أكثر واقعية.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #274e13;"&gt;Controller&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Http\Request;

public function store(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'title' =&amp;gt; ['required', 'string', 'min:3', 'max:255'],
        'body' =&amp;gt; ['required', 'string', 'min:10'],
        'email' =&amp;gt; ['required', 'email'],
    ]);

    return redirect()
        -&amp;gt;route('articles.index')
        -&amp;gt;with('success', 'تم إرسال المقال بنجاح.');
}
&lt;/pre&gt;&lt;p&gt;لدينا هنا ثلاثة حقول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
body
email
&lt;/pre&gt;
&lt;p&gt;وكل واحد لديه قواعد مختلفة.&lt;/p&gt;&lt;p&gt;إذا نجحت Validation، نحصل على البيانات التي اجتازت التحقق داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated
&lt;/pre&gt;&lt;p&gt;وهذه نقطة مهمة جدًا.&lt;/p&gt;&lt;p&gt;بدلًا من الاعتماد على كل البيانات الموجودة في Request، أصبح لدينا مجموعة بيانات تم التحقق منها.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;لماذا نستخدم $validated؟&lt;/h3&gt;&lt;p&gt;لنفترض أن Request يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
body
email
admin
unexpected_field
&lt;/pre&gt;&lt;p&gt;بينما قواعد Validation تسمح فقط بـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title
body
email
&lt;/pre&gt;&lt;p&gt;بعد Validation، من الأفضل أن تعتمد على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated
&lt;/pre&gt;&lt;p&gt;بدل التعامل مع كل البيانات الواردة بشكل عشوائي.&lt;/p&gt;&lt;p&gt;مثلًا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validate([
    'title' =&amp;gt; ['required', 'string'],
    'body' =&amp;gt; ['required', 'string'],
]);
&lt;/pre&gt;
&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$title = $validated['title'];
$body = $validated['body'];
&lt;/pre&gt;&lt;p&gt;هذا يجعل الكود أكثر وضوحًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إعادة التوجيه بعد نجاح العملية&lt;/h3&gt;&lt;p&gt;بعد نجاح Form، غالبًا لا نريد ترك المستخدم في نفس الطلب.&lt;/p&gt;&lt;p&gt;يمكننا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return redirect()
    -&amp;gt;route('articles.index');
&lt;/pre&gt;
&lt;p&gt;أو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return redirect('/articles');
&lt;/pre&gt;&lt;p&gt;وفي تطبيقات CRUD، غالبًا يكون السيناريو:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;POST
↓
Validation
↓
حفظ البيانات
↓
Redirect
↓
صفحة القائمة
&lt;/pre&gt;&lt;p&gt;وهذا يمنع بعض المشاكل التي قد تحدث عند إعادة إرسال Form بعد تحديث الصفحة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إرسال رسالة نجاح&lt;/h3&gt;&lt;p&gt;يمكننا أيضًا إرسال رسالة إلى الصفحة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return redirect()
    -&amp;gt;route('articles.index')
    -&amp;gt;with('success', 'تم إنشاء المقال بنجاح.');
&lt;/pre&gt;&lt;p&gt;ثم في Blade:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@if (session('success'))
    &amp;lt;div&amp;gt;
        {{ session('success') }}
    &amp;lt;/div&amp;gt;
@endif
&lt;/pre&gt;&lt;p&gt;وهكذا تظهر للمستخدم رسالة مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;تم إنشاء المقال بنجاح.
&lt;/pre&gt;&lt;p&gt;سنستخدم هذا الأسلوب كثيرًا في تطبيقات CRUD.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Form Request&lt;/h3&gt;&lt;p&gt;عندما يكون Controller صغيرًا، يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate()
&lt;/pre&gt;&lt;p&gt;مباشرة.&lt;/p&gt;&lt;p&gt;لكن ماذا يحدث عندما يصبح لدينا Form كبير وقواعد Validation كثيرة؟&lt;/p&gt;&lt;p&gt;يمكننا استخدام &lt;strong&gt;Form Request&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Form Request هو Class مخصص يجمع:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Validation Rules.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Authorization Logic.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;منطق متعلق بالطلب.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;ويمكن إنشاء Form Request باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:request StoreArticleRequest
&lt;/pre&gt;&lt;p&gt;وتقوم Laravel بوضعه داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Http/Requests
&lt;/pre&gt;&lt;p&gt;وفقًا لوثائق Laravel الرسمية.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;إنشاء StoreArticleRequest&lt;/h3&gt;&lt;p&gt;نفذ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:request StoreArticleRequest
&lt;/pre&gt;&lt;p&gt;سيتم إنشاء:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;app/Http/Requests/StoreArticleRequest.php
&lt;/pre&gt;
&lt;p&gt;وستجد داخله Methods مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;authorize()
&lt;/pre&gt;
&lt;p&gt;و:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;rules()
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;كتابة Validation Rules داخل Form Request&lt;/h3&gt;&lt;p&gt;يمكنك كتابة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function rules(): array
{
    return [
        'title' =&amp;gt; ['required', 'string', 'min:3', 'max:255'],
        'body' =&amp;gt; ['required', 'string', 'min:10'],
        'email' =&amp;gt; ['required', 'email'],
    ];
}
&lt;/pre&gt;&lt;p&gt;وبذلك أصبح Validation منفصلًا عن Controller.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;authorize()&lt;/h3&gt;&lt;p&gt;Form Request يحتوي أيضًا على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function authorize(): bool
{
    return true;
}
&lt;/pre&gt;&lt;p&gt;هذه Method تحدد ما إذا كان المستخدم مسموحًا له بتنفيذ العملية.&lt;/p&gt;&lt;p&gt;في البداية يمكن أن تكون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;return true;
&lt;/pre&gt;&lt;p&gt;لكن لاحقًا عندما نتعلم Authentication وAuthorization وPolicies، يمكن استخدام هذه Method للتحكم في الصلاحيات.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام Form Request داخل Controller&lt;/h3&gt;&lt;p&gt;بدلًا من:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
&lt;/pre&gt;&lt;p&gt;نستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Http\Requests\StoreArticleRequest;

public function store(StoreArticleRequest $request)
{
    //
}
&lt;/pre&gt;&lt;p&gt;الميزة هنا أن Laravel تقوم بتنفيذ Validation قبل الوصول إلى Controller Method.&lt;/p&gt;&lt;p&gt;إذا نجحت Validation، يصل الطلب إلى:&lt;/p&gt;&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;store()
&lt;/pre&gt;&lt;p&gt;أما إذا فشلت، يتم التعامل مع الأخطاء وإعادة المستخدم بالطريقة المناسبة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;استخدام validated()&lt;/h3&gt;&lt;p&gt;بعد نجاح Form Request، يمكنك الحصول على البيانات التي اجتازت Validation باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$validated = $request-&amp;gt;validated();
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(StoreArticleRequest $request)
{
    $validated = $request-&amp;gt;validated();

    // حفظ البيانات

    return redirect()
        -&amp;gt;route('articles.index');
}
&lt;/pre&gt;&lt;p&gt;وهذا يجعل Controller نظيفًا جدًا.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;متى أستخدم Request ومتى أستخدم Form Request؟&lt;/h3&gt;&lt;p&gt;في المشاريع الصغيرة، يمكنك البدء بـ:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    ...
]);
&lt;/pre&gt;&lt;p&gt;وهذا بسيط وسهل للمبتدئين.&lt;/p&gt;&lt;p&gt;لكن عندما تصبح عملية Validation كبيرة أو يتم استخدامها في أكثر من مكان، يكون Form Request أكثر تنظيمًا.&lt;/p&gt;&lt;p&gt;يمكنك التفكير بهذه الطريقة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Validation بسيطة
        ↓
$request-&amp;gt;validate()
&lt;/pre&gt;&lt;p&gt;أما:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Validation كبيرة ومعقدة
        ↓
Form Request
&lt;/pre&gt;&lt;h3 style="text-align: right;"&gt;مثال كامل باستخدام Form Request&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;إنشاء Request&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:request StoreArticleRequest
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;القواعد&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function rules(): array
{
    return [
        'title' =&amp;gt; ['required', 'string', 'min:3', 'max:255'],
        'body' =&amp;gt; ['required', 'string', 'min:10'],
    ];
}
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;Controller&lt;/b&gt;&lt;/p&gt;

&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use App\Http\Requests\StoreArticleRequest;

public function store(StoreArticleRequest $request)
{
    $validated = $request-&amp;gt;validated();

    return redirect()
        -&amp;gt;route('articles.index')
        -&amp;gt;with('success', 'تم إنشاء المقال بنجاح.');
}
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;Form&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST" action="{{ route('articles.store') }}"&amp;gt;

    @csrf

    &amp;lt;input
        type="text"
        name="title"
        value="{{ old('title') }}"
    &amp;gt;

    @error('title')
        &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
    @enderror

    &amp;lt;textarea name="body"&amp;gt;{{ old('body') }}&amp;lt;/textarea&amp;gt;

    @error('body')
        &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
    @enderror

    &amp;lt;button type="submit"&amp;gt;
        حفظ
    &amp;lt;/button&amp;gt;

&amp;lt;/form&amp;gt;
&lt;/pre&gt;&lt;p&gt;الآن أصبحت لدينا دورة كاملة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Blade Form
   ↓
POST Request
   ↓
StoreArticleRequest
   ↓
Validation
   ↓
Controller
   ↓
Validated Data
   ↓
Database
&lt;/pre&gt;&lt;p&gt;سنضيف قاعدة البيانات في الدروس القادمة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;بعض قواعد Validation المهمة&lt;/h3&gt;&lt;p&gt;هناك عدد كبير جدًا من قواعد Validation في Laravel، لكن كمبتدئ من المفيد أن تتعرف على أشهرها:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;required
&lt;/pre&gt;&lt;p&gt;القيمة مطلوبة.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;nullable
&lt;/pre&gt;&lt;p&gt;القيمة يمكن أن تكون &lt;code inline=""&gt;null&lt;/code&gt;.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;string
&lt;/pre&gt;&lt;p&gt;القيمة يجب أن تكون نصًا.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;integer
&lt;/pre&gt;&lt;p&gt;القيمة يجب أن تكون عددًا صحيحًا.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;numeric
&lt;/pre&gt;&lt;p&gt;القيمة يجب أن تكون رقمًا.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;email
&lt;/pre&gt;&lt;p&gt;القيمة يجب أن تكون بريدًا إلكترونيًا صالحًا.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;url
&lt;/pre&gt;&lt;p&gt;القيمة يجب أن تكون رابطًا صالحًا.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;min
&lt;/pre&gt;&lt;p&gt;تحديد الحد الأدنى.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;max
&lt;/pre&gt;&lt;p&gt;تحديد الحد الأقصى.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;date
&lt;/pre&gt;&lt;p&gt;التحقق من التاريخ.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;boolean
&lt;/pre&gt;&lt;p&gt;التحقق من قيمة منطقية.&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;confirmed
&lt;/pre&gt;&lt;p&gt;مفيد في حقول التأكيد مثل كلمة المرور.&lt;/p&gt;&lt;p&gt;Laravel توفر مجموعة واسعة من القواعد الإضافية، ويمكن الرجوع إلى وثائق Validation الرسمية لمعرفة التفاصيل والصيغ المتاحة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;Validation للحقول المتداخلة&lt;/h3&gt;&lt;p&gt;Laravel تسمح أيضًا بالتحقق من بيانات متداخلة باستخدام صيغة النقطة.&lt;/p&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    'author.name' =&amp;gt; ['required', 'string'],
    'author.email' =&amp;gt; ['required', 'email'],
]);
&lt;/pre&gt;&lt;p&gt;إذا كانت البيانات بهذا الشكل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;author
    name
    email
&lt;/pre&gt;&lt;p&gt;يمكنك الوصول إليها باستخدام هذه الصيغة.&lt;/p&gt;&lt;p&gt;هذه الميزة تصبح مفيدة جدًا عندما تتعامل مع Forms تحتوي على بيانات منظمة أو Arrays متداخلة.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التحقق من الحقول الفريدة&lt;/h3&gt;&lt;p&gt;عند إنشاء حساب مستخدم مثلًا، قد نريد أن يكون البريد الإلكتروني غير مستخدم من قبل.&lt;/p&gt;&lt;p&gt;يمكن استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'email' =&amp;gt; ['required', 'email', 'unique:users,email']
&lt;/pre&gt;&lt;p&gt;الفكرة هنا أن Laravel تتحقق من عدم وجود قيمة مكررة وفق قاعدة البيانات.&lt;/p&gt;&lt;p&gt;سنعود إلى هذه القاعدة بشكل أعمق عندما نصل إلى Database وEloquent.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;التحقق من وجود قيمة في قاعدة البيانات&lt;/h3&gt;&lt;p&gt;يمكن أيضًا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;exists
&lt;/pre&gt;&lt;p&gt;مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'category_id' =&amp;gt; ['required', 'exists:categories,id']
&lt;/pre&gt;&lt;p&gt;وهذا يعني أن &lt;code inline=""&gt;category_id&lt;/code&gt; يجب أن تكون موجودة في جدول:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;categories
&lt;/pre&gt;&lt;p&gt;داخل العمود:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;id
&lt;/pre&gt;&lt;p&gt;هذه القواعد ستكون مهمة جدًا عندما نبدأ في التعامل مع العلاقات بين الجداول.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;ماذا يحدث عند فشل Validation؟&lt;/h3&gt;&lt;p&gt;من المهم أن تفهم دورة Validation.&lt;/p&gt;&lt;p&gt;لنفترض أن المستخدم أرسل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;title = ""
body = "مقال"
&lt;/pre&gt;&lt;p&gt;ولدينا:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required'],
&lt;/pre&gt;&lt;p&gt;ستفشل Validation.&lt;/p&gt;&lt;p&gt;في الطلب التقليدي، Laravel تعيد المستخدم إلى الصفحة السابقة وتوفر رسائل الأخطاء والبيانات القديمة التي يمكن استخدامها في View.&lt;/p&gt;&lt;p&gt;ثم يمكننا عرض:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@error('title')
    &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
@enderror
&lt;/pre&gt;&lt;p&gt;واستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;value="{{ old('title') }}"
&lt;/pre&gt;&lt;p&gt;وهكذا يحصل المستخدم على تجربة واضحة بدل ظهور خطأ غير مفهوم.&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;الفرق بين Validation في Controller وForm Request&lt;/h3&gt;&lt;p&gt;يمكن تلخيص الفرق هكذا:&lt;/p&gt;&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;الطريقة&lt;/th&gt;&lt;th&gt;الاستخدام&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;$request-&amp;gt;validate()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;Validation بسيطة وسريعة&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Form Request&lt;/td&gt;&lt;td&gt;Validation منظمة وأكثر تعقيدًا&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;$request-&amp;gt;validated()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;الحصول على البيانات التي تم التحقق منها&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;$errors&lt;/code&gt;&lt;/td&gt;&lt;td&gt;الوصول إلى أخطاء Validation داخل View&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;@error&lt;/code&gt;&lt;/td&gt;&lt;td&gt;عرض خطأ حقل محدد&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;code inline=""&gt;old()&lt;/code&gt;&lt;/td&gt;&lt;td&gt;إعادة البيانات القديمة إلى Form&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;p&gt;هذه الأدوات سترافقك في معظم تطبيقات Laravel التي تحتوي على Forms.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;&lt;span style="color: #4c1130;"&gt;مثال عملي شامل&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لنقم ببناء Form بسيط لإنشاء مقال.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الأولى: Route&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Route::get('/articles/create', [ArticleController::class, 'create'])
    -&amp;gt;name('articles.create');

Route::post('/articles', [ArticleController::class, 'store'])
    -&amp;gt;name('articles.store');
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الثانية: Controller&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function create()
{
    return view('articles.create');
}
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
{
    $validated = $request-&amp;gt;validate([
        'title' =&amp;gt; ['required', 'string', 'min:3', 'max:255'],
        'body' =&amp;gt; ['required', 'string', 'min:10'],
    ]);

    return redirect()
        -&amp;gt;route('articles.index')
        -&amp;gt;with('success', 'تم إنشاء المقال بنجاح.');
}
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;الخطوة الثالثة: View&lt;/b&gt;&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@extends('layouts.app')

@section('title', 'إضافة مقال')

@section('content')

    &amp;lt;h1&amp;gt;إضافة مقال&amp;lt;/h1&amp;gt;

    @if ($errors-&amp;gt;any())

        &amp;lt;div&amp;gt;
            &amp;lt;ul&amp;gt;
                @foreach ($errors-&amp;gt;all() as $error)
                    &amp;lt;li&amp;gt;{{ $error }}&amp;lt;/li&amp;gt;
                @endforeach
            &amp;lt;/ul&amp;gt;
        &amp;lt;/div&amp;gt;

    @endif

    &amp;lt;form method="POST" action="{{ route('articles.store') }}"&amp;gt;

        @csrf

        &amp;lt;div&amp;gt;
            &amp;lt;label for="title"&amp;gt;العنوان&amp;lt;/label&amp;gt;

            &amp;lt;input
                type="text"
                name="title"
                id="title"
                value="{{ old('title') }}"
            &amp;gt;

            @error('title')
                &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
            @enderror
        &amp;lt;/div&amp;gt;

        &amp;lt;div&amp;gt;
            &amp;lt;label for="body"&amp;gt;المحتوى&amp;lt;/label&amp;gt;

            &amp;lt;textarea
                name="body"
                id="body"
            &amp;gt;{{ old('body') }}&amp;lt;/textarea&amp;gt;

            @error('body')
                &amp;lt;p&amp;gt;{{ $message }}&amp;lt;/p&amp;gt;
            @enderror
        &amp;lt;/div&amp;gt;

        &amp;lt;button type="submit"&amp;gt;
            حفظ المقال
        &amp;lt;/button&amp;gt;

    &amp;lt;/form&amp;gt;

@endsection
&lt;/pre&gt;&lt;p&gt;أصبح لدينا الآن نموذج حقيقي يستطيع:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;عرض Form.&lt;/li&gt;&lt;li&gt;استقبال البيانات.&lt;/li&gt;&lt;li&gt;حماية الطلب باستخدام CSRF.&lt;/li&gt;&lt;li&gt;التحقق من البيانات.&lt;/li&gt;&lt;li&gt;عرض الأخطاء.&lt;/li&gt;&lt;li&gt;إعادة البيانات القديمة.&lt;/li&gt;&lt;li&gt;إعادة توجيه المستخدم بعد النجاح.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;h3 style="text-align: right;"&gt;أخطاء شائعة في Requests وValidation&lt;/h3&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;1 - نسيان &lt;code inline=""&gt;@csrf&lt;/code&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;من أكثر الأخطاء شيوعًا عند إنشاء POST Form:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;form method="POST"&amp;gt;
&lt;/pre&gt;&lt;p&gt;بدون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@csrf
&lt;/pre&gt;&lt;p&gt;اجعل إضافة &lt;code inline=""&gt;@csrf&lt;/code&gt; عادة ثابتة في Forms التي تحتاجها.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;2 - عدم تحديد name&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كتبت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;input type="text" id="title"&amp;gt;
&lt;/pre&gt;&lt;p&gt;بدون:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;name="title"
&lt;/pre&gt;&lt;p&gt;فلن تحصل على الحقل باسم &lt;code inline=""&gt;title&lt;/code&gt; ضمن بيانات Form كما تتوقع.&lt;/p&gt;&lt;p&gt;الصحيح:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;input
    type="text"
    name="title"
    id="title"
&amp;gt;
&lt;/pre&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;3 - اختلاف اسم الحقل عن اسم Validation&lt;/b&gt;&lt;/p&gt;&lt;p&gt;إذا كان Form يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;input name="article_title"&amp;gt;
&lt;/pre&gt;&lt;p&gt;ثم كتبت:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required']
&lt;/pre&gt;&lt;p&gt;فهناك عدم تطابق.&lt;/p&gt;&lt;p&gt;يجب أن تتفق أسماء الحقول مع Validation Rules.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;4 - نسيان &lt;code inline=""&gt;old()&lt;/code&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;ليس خطأ تقنيًا قاتلًا، لكنه يجعل تجربة المستخدم أسوأ، خصوصًا في Forms الكبيرة.&lt;/p&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;value="{{ old('title') }}"
&lt;/pre&gt;&lt;p&gt;عند الحاجة.&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;b&gt;5 - قبول بيانات غير متحقق منها&lt;/b&gt;&lt;/p&gt;&lt;p&gt;لا تعتمد على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;all()
&lt;/pre&gt;&lt;p&gt;كبديل عن Validation عندما تكون البيانات ستستخدم في عمليات حساسة.&lt;/p&gt;&lt;p&gt;الأفضل أن تتحقق من البيانات ثم تتعامل مع البيانات التي اجتازت Validation.&lt;/p&gt;&lt;h3&gt;تحقق من البيانات عند دخولها إلى التطبيق&lt;/h3&gt;&lt;p&gt;لا تنتظر حتى تصل البيانات إلى قاعدة البيانات ثم تكتشف أن هناك مشكلة.&lt;/p&gt;&lt;p&gt;استخدم Validation قبل المعالجة أو الحفظ.&lt;/p&gt;&lt;h3&gt;استخدم قواعد واضحة&lt;/h3&gt;&lt;p&gt;بدل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; ['required']
&lt;/pre&gt;&lt;p&gt;إذا كان لديك متطلبات إضافية، استخدم قواعد مناسبة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'title' =&amp;gt; [
    'required',
    'string',
    'min:3',
    'max:255'
]
&lt;/pre&gt;&lt;h3&gt;استخدم Form Requests عند زيادة التعقيد&lt;/h3&gt;&lt;p&gt;عندما يبدأ Controller بالامتلاء بقواعد Validation، انقلها إلى Form Request.&lt;/p&gt;&lt;h3&gt;اعرض الأخطاء بوضوح&lt;/h3&gt;&lt;p&gt;استخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@error('field')
&lt;/pre&gt;&lt;p&gt;قرب الحقل الذي توجد فيه المشكلة.&lt;/p&gt;&lt;h3&gt;لا تثق ببيانات المستخدم&lt;/h3&gt;&lt;p&gt;حتى لو كان Form يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;&amp;lt;input type="number"&amp;gt;
&lt;/pre&gt;&lt;p&gt;هذا لا يعني أن البيانات القادمة إلى الخادم آمنة أو صحيحة.&lt;/p&gt;&lt;p&gt;التحقق الحقيقي يجب أن يحدث على الخادم باستخدام Laravel Validation.&lt;/p&gt;&lt;p&gt;&lt;b&gt;&lt;span style="color: #4c1130;"&gt;تمرين عملي&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;قم الآن بإنشاء Form لإضافة منتج.&lt;/p&gt;&lt;p&gt;يجب أن يحتوي على:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;name
price
description
email
&lt;/pre&gt;&lt;p&gt;ثم أنشئ Validation:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;'name' =&amp;gt; ['required', 'string', 'min:3', 'max:255'],
'price' =&amp;gt; ['required', 'numeric', 'min:0'],
'description' =&amp;gt; ['required', 'string', 'min:10'],
'email' =&amp;gt; ['required', 'email'],
&lt;/pre&gt;&lt;p&gt;بعد ذلك:&lt;/p&gt;&lt;p style="text-align: right;"&gt;&lt;/p&gt;&lt;ol style="text-align: right;"&gt;&lt;li&gt;أنشئ Route لعرض Form.&lt;/li&gt;&lt;li&gt;أنشئ Route من نوع POST لاستقبال البيانات.&lt;/li&gt;&lt;li&gt;أنشئ Method باسم &lt;code inline=""&gt;create()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;أنشئ Method باسم &lt;code inline=""&gt;store()&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;استخدم &lt;code inline=""&gt;@csrf&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;اعرض أخطاء كل حقل باستخدام &lt;code inline=""&gt;@error&lt;/code&gt;.&lt;/li&gt;&lt;li&gt;استخدم &lt;code inline=""&gt;old()&lt;/code&gt; لإعادة البيانات السابقة.&lt;/li&gt;&lt;li&gt;بعد نجاح Validation، أعد توجيه المستخدم إلى صفحة المنتجات.&lt;/li&gt;&lt;li&gt;أرسل رسالة نجاح باستخدام &lt;code inline=""&gt;with()&lt;/code&gt;.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;بعد تنفيذ التمرين، حاول تحويل Validation من Controller إلى:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:request StoreProductRequest
&lt;/pre&gt;&lt;p&gt;ثم ضع القواعد داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;rules()
&lt;/pre&gt;&lt;p&gt;واستخدم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validated();
&lt;/pre&gt;&lt;p&gt;داخل Controller.&lt;/p&gt;&lt;p&gt;في هذا الدرس انتقلنا من مجرد عرض البيانات إلى &lt;strong&gt;استقبال البيانات القادمة من المستخدم والتعامل معها بطريقة صحيحة&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;تعلمنا أن HTTP Request يحتوي على البيانات والمعلومات المرتبطة بالطلب، ويمكننا الوصول إليه في Controller باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;use Illuminate\Http\Request;
&lt;/pre&gt;&lt;p&gt;ثم:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;public function store(Request $request)
&lt;/pre&gt;&lt;p&gt;وتعلمنا قراءة البيانات باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;input('title');
&lt;/pre&gt;&lt;p&gt;ثم تعرفنا على Validation باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validate([
    ...
]);
&lt;/pre&gt;&lt;p&gt;وتعلمنا قواعد مهمة مثل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;required
string
integer
numeric
email
min
max
nullable
date
unique
exists
&lt;/pre&gt;&lt;p&gt;كما تعلمنا كيفية عرض الأخطاء في Blade باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;@error('title')
    {{ $message }}
@enderror
&lt;/pre&gt;&lt;p&gt;وتعلمنا استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;old('title')
&lt;/pre&gt;&lt;p&gt;لإعادة البيانات التي أدخلها المستخدم إلى النموذج بعد فشل Validation.&lt;/p&gt;&lt;p&gt;ثم انتقلنا إلى &lt;strong&gt;Form Requests&lt;/strong&gt; باستخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;php artisan make:request StoreArticleRequest
&lt;/pre&gt;&lt;p&gt;وتعلمنا وضع Validation Rules داخل:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;rules()
&lt;/pre&gt;&lt;p&gt;ثم استخدام:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;$request-&amp;gt;validated();
&lt;/pre&gt;&lt;p&gt;للحصول على البيانات التي اجتازت التحقق.&lt;/p&gt;&lt;p&gt;وأصبح لدينا الآن تصور أوضح لدورة Form كاملة:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Blade Form
    ↓
HTTP Request
    ↓
Route
    ↓
Controller / Form Request
    ↓
Validation
    ↓
Validated Data
    ↓
Database
    ↓
Redirect
    ↓
Blade View
&lt;/pre&gt;&lt;p&gt;وهنا نصل إلى نقطة مهمة جدًا في الكورس.&lt;/p&gt;&lt;p&gt;لقد تعلمنا حتى الآن:&lt;/p&gt;
&lt;pre class="sq-code" dir="ltr" style="text-align: left;"&gt;Routes
Controllers
Views
Blade
Requests
Validation
&lt;/pre&gt;&lt;p&gt;والخطوة الطبيعية التالية هي أن نتعلم أين ستذهب البيانات بعد نجاح Validation.&lt;/p&gt;&lt;p&gt;وهنا سنبدأ بالدخول إلى عالم &lt;strong&gt;Database وMigrations&lt;/strong&gt;، ونتعلم كيفية إنشاء قاعدة البيانات والجداول باستخدام Laravel، وكيف يمكن للتطبيق إنشاء وتعديل بنية الجداول بطريقة منظمة بدل التعامل معها يدويًا.&lt;/p&gt;&lt;p&gt;في الدرس القادم سنبدأ مع &lt;strong&gt;Database وMigrations في Laravel&lt;/strong&gt;، ثم ننتقل بعد ذلك إلى Models وEloquent للتعامل مع البيانات بطريقة Laravel المميزة.&lt;/p&gt;</content><link href="https://www.nusurtech.ca/feeds/6370452062501607902/comments/default" rel="replies" title="تعليقات الرسالة" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-requests-validation.html#comment-form" rel="replies" title="0 تعليقات" type="text/html"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6370452062501607902" rel="edit" type="application/atom+xml"/><link href="https://www.blogger.com/feeds/5221909926006253414/posts/default/6370452062501607902" rel="self" type="application/atom+xml"/><link href="https://www.nusurtech.ca/2026/09/laravel-requests-validation.html" rel="alternate" title="تمرير البيانات بين Controller و View في Laravel" type="text/html"/><author><name>محمد تركي العلوش</name><uri>http://www.blogger.com/profile/03509222840006865504</uri><email>noreply@blogger.com</email><gd:image height="32" rel="http://schemas.google.com/g/2005#thumbnail" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6G3WDEI0sLmH3DuSft2y22MkQlT3g-MgX_BbNGxg2d36hXfVLesgVhLyHZXB5DZeGCZ2YSZuSpnXz-_6xT_DBjTjSud2t45-68hW-v2hBEfWdyvVW0BYnVBxE5ZDsvzo-iP_U4UCMcPxIMAF449SPugFlTpK9y-ISVi3xNv_vTUiqyg/s1600/photo_2026-03-25_16-12-15.jpg" width="32"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvuOYnEUgy8CWXGhTwIJx0V4_GdVtYjCohQ42_Y6In5Dc4ys0R1Qh-j2oYtGLMP30-ntCKig2eB_hyIbpPemaOS__tWL5hyrtwMnJU0wotoG4xYo_Vk8tlEXZCCJbbOtNsPOCbZgvClzxlF2kOUwjse8RV-xo52zKZ6RwmDngXQSd9LhIoFVu4YUsEDpa3/s72-c/imageedit_1_9071720482.webp" width="72"/><thr:total>0</thr:total></entry></feed>