Database& Performance.
إزاي Magento بيقرا، بيفهرس، وبيكاش الـ data — والـ CLI والـ APIs اللي بتشغّل كل ده. الجزء اللي بيفرّق بين junior و mid-level في الإنترفيو.
أداء طبقة البيانات في Magento 2 بيعتمد على إنك تستخدم الـ Collections صح: تحدّد الأعمدة والفلاتر وتتجنّب الـ queries جوّه loops. الـ Data Patches بتعدّل البيانات مرة واحدة وقت setup:upgrade، والـ Cron بيشغّل الشغل الدوري، وأنواع الـ Cache بتقلّل الحسابات المتكرّرة، وكل ده بيتدار بأوامر bin/magento.
Collections & Queries
إزاي تجيب بيانات كتير بكفاءة. أخطاء الـ performance هنا بتقتل الـ storefront، والـ interviewers بيركّزوا عليها.
الـ Collection بتبني الـ query تدريجيًا. متتنفّذش غير لما تعمل عليها iterate أو تنادي getItems() — ده اسمه lazy loading.
$collection = $this->productCollectionFactory->create(); $collection ->addAttributeToSelect(['name', 'price']) ->addFieldToFilter('status', Status::STATUS_ENABLED) ->setOrder('price', 'DESC') ->setPageSize(20); foreach ($collection as $product) { // Query runs on first iteration }
- addFieldToFilter — للـ flat tables والأعمدة العادية.
- addAttributeToFilter — للـ EAV entities (product, category, customer) بيعمل الـ JOINs اللازمة أوتوماتيك.
لو محتاج SQL مباشر، استخدم الـ connection بتاع الـ ResourceModel مع الـ bind parameters — عمرك ما تحط قيم في الـ query يدوي (SQL injection).
$connection = $this->resource->getConnection(); $table = $this->resource->getTableName('vendor_log'); $select = $connection->select() ->from($table) ->where('status = ?', $status); // bound param $rows = $connection->fetchAll($select);
Data & Schema Patches
الطريقة الحديثة لتعديل الـ DB. بديل الـ InstallData/UpgradeData القديمة.
الـ Data Patch بيتنفّذ مرة واحدة، وMagento بيسجّله في جدول patch_list عشان ميتكررش.
class AddConfig implements DataPatchInterface { public function __construct( private readonly ModuleDataSetupInterface $setup ) {} public function apply() { $this->setup->startSetup(); // insert / update data here $this->setup->endSetup(); } public static function getDependencies(): array { return []; // other patches to run first } public function getAliases(): array { return []; } }
Indexers
بيحوّلوا بيانات الـ EAV المعقدة لجداول مسطّحة سريعة عشان الـ storefront يفتح بسرعة.
حساب الأسعار، الـ stock، والـ category products وقت كل request هيبقى بطيء جدًا. الـ indexer بيحسبهم مقدمًا ويخزّنهم في جداول جاهزة للقراءة.
php bin/magento indexer:status php bin/magento indexer:reindex php bin/magento indexer:set-mode schedule
Cron Jobs
المهام المجدولة — الـ indexing, emails, reindex, cache flush كلها بتعتمد على الـ cron.
بتعرّف الـ cron job في crontab.xml، وبتربطه بـ class فيه method execute().
<config> <group id="default"> <job name="vendor_cleanup" instance="Vendor\Module\Cron\Cleanup" method="execute"> <!-- every day at 03:00 --> <schedule>0 3 * * *</schedule> </job> </group> </config>
Cache Types
الـ cache هو سر سرعة Magento. اعرف الأنواع، وإمتى تعمل flush مقابل clean.
- config — نتائج تجميع كل الـ XML config.
- layout — بنية الـ layout المبنية.
- block_html — ناتج render الـ blocks.
- full_page (FPC) — صفحات كاملة؛ عادةً على Varnish في production.
- collections / db_ddl / eav — نتائج queries وبنية الـ schema.
php bin/magento cache:status php bin/magento cache:clean config php bin/magento cache:flush
CLI Commands
اعرف الأوامر الأساسية، واعرف تكتب command خاص بيك — سؤال عملي متكرر.
setup:upgrade # apply module + patches setup:di:compile # generate DI classes setup:static-content:deploy # build assets cache:flush indexer:reindex module:enable Vendor_Module deploy:mode:set production
بتورّث من Symfony\Component\Console\Command\Command وبتسجّله في الـ di.xml تحت الـ CommandList.
class Hello extends Command { protected function configure(): void { $this->setName('vendor:hello') ->setDescription('Prints a greeting'); } protected function execute( InputInterface $input, OutputInterface $output ): int { $output->writeln('<info>Hello Magento</info>'); return Command::SUCCESS; } }
<type name="Magento\Framework\Console\CommandList"> <arguments> <argument name="commands" xsi:type="array"> <item name="vendorHello" xsi:type="object"> Vendor\Module\Console\Command\Hello </item> </argument> </arguments> </type>
REST & GraphQL APIs
إزاي تعرّض الـ service contracts بتاعتك كـ web APIs — بمجرد config.
بتربط route بـ method في repository، وبتحدد الـ ACL للصلاحيات. Magento بيعمل الـ serialization أوتوماتيك من الـ interface.
<routes> <route url="/V1/logs/:id" method="GET"> <service class="Vendor\Module\Api\LogRepositoryInterface" method="getById"/> <resources> <resource ref="Vendor_Module::view"/> </resources> </route> </routes>
Message Queues
للمعالجة غير المتزامنة (asynchronous). بيظهر في إنترفيوهات المستوى الأعلى ومشاريع الـ enterprise.
بدل ما تعمل مهمة تقيلة (زي export أو sync لـ ERP) وقت الـ request، بتبعتها كـ message لـ queue، و consumer بياخدها ويعالجها في الخلفية.
- Publisher — بيحط الـ message في الـ queue.
- Consumer — بيشتغل عن طريق الـ CLI ويعالج الرسائل.
- الإعداد في: communication.xml، queue_publisher.xml، queue_consumer.xml، queue_topology.xml.
php bin/magento queue:consumers:list php bin/magento queue:consumers:start myConsumer
اليوم التاني خلص ✓
دلوقتي بتفهم إزاي الـ data بتتحرك في Magento — من الـ collection للـ index للـ cache للـ API. دي المواضيع اللي بتفرّق في الإنترفيو التقني.
اللي جاي: الـ Adminhtml، الـ ACL، الـ system config، والـ UI Components (grids & forms).
خلّصت الدرس؟علّمه عشان تتابع تقدّمك في الكورس.
أسئلة شائعة
إمتى الـ Collection query بتتنفّذ فعلًا في Magento 2؟
مش وقت ما تبني الـ collection، لأن الـ Collection بتبني الـ query تدريجيًا وده اسمه lazy loading. الـ query بتتنفّذ أول ما تحتاج الـ data فعلًا، زي أول iteration في foreach أو لما تنادي getItems().
ما الفرق بين addFieldToFilter و addAttributeToFilter في Magento 2؟
addFieldToFilter بتستخدمها مع الـ flat tables والأعمدة العادية. أما addAttributeToFilter فمعمولة للـ EAV entities زي الـ product والـ category والـ customer، وبتعمل الـ JOINs اللازمة أوتوماتيك.
إزاي أحسّن أداء الـ Collections في Magento 2؟
متعملش load كامل جوّه loop، ومتجيبش كل الأعمدة بـ addAttributeToSelect('*') في production. حدّد الحقول اللي محتاجها بس، وفلتر بـ addFieldToFilter، واستخدم setPageSize() عشان متجيبش آلاف الصفوف مرة واحدة.
ما الفرق بين Data Patch و Schema Patch في Magento 2؟
الـ Schema Patch بيعدّل بنية الـ DB في التعديلات المعقدة اللي db_schema.xml مش بيغطيها، والـ Data Patch بيزرع أو يعدّل بيانات فعلية زي config أو attributes. الاتنين بيتنفّذوا مرة واحدة بس، وMagento بيسجّلهم في جدول patch_list عشان ميتكرروش، وهما البديل الحديث لـ InstallData وUpgradeData.
ما الفرق بين cache:clean و cache:flush في Magento 2؟
cache:clean بيمسح بس العناصر اللي Magento مسؤول عنها عن طريق الـ tags ويسيب الباقي. أما cache:flush فبيفضّي الـ cache storage بالكامل، بما فيه بيانات تطبيقات تانية شايلة نفس الـ Redis، فهو أثقل وأشمل.
إزاي أعمل custom CLI command في Magento 2؟
بتعمل class بيورّث من Symfony\Component\Console\Command\Command، تحدد اسمه في configure() بـ setName()، وتكتب الشغل في execute() وترجّع Command::SUCCESS. بعدها بتسجّله في di.xml كـ item جوّه الـ commands argument بتاع Magento\Framework\Console\CommandList.
إزاي أكتب SQL query مباشرة بأمان في Magento 2؟
خد الـ connection بـ getConnection() وابني الـ query بـ select()، وحط القيم كـ bound parameters زي where('status = ?', $status). عمرك ما تحط القيم جوّه الـ query يدوي، لأن ده بيفتح باب SQL injection.