Zend Engine कैसे काम करता है
सोर्स से ऑपकोड और फिर निष्पादन तक PHP का अनुक्रम देखें।
Zend Engine कैसे काम करता है, CoddyKit पर PHP Academy का एक निःशुल्क पाठ है। यह 4 में से 1वाँ पाठ है। आप नीचे पूरा पाठ निःशुल्क पढ़ सकते हैं—फिर अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर के साथ ब्राउज़र में इसका व्यावहारिक अभ्यास कर सकते हैं। यह PHP Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। PHP Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
इंजन के भीतर
PHP को स्रोत से पंक्ति-दर-पंक्ति व्याख्यायित नहीं किया जाता। Zend Engine आपकी स्क्रिप्ट को ऑपकोड नामक मध्यवर्ती निरूपण में संकलित करता है, फिर एक आभासी मशीन उन्हें निष्पादित करती है। इस प्रसंस्करण-क्रम को समझने से प्रदर्शन, OPcache और JIT स्पष्ट होते हैं।
इस पाठ में स्रोत → टोकन → AST → ऑपकोड → VM निष्पादन का क्रम समझाया गया है।
प्रसंस्करण-क्रम
PHP फ़ाइल के प्रत्येक अनुरोध में चार चरण होते हैं:
- शाब्दिक विश्लेषण — स्रोत-पाठ → टोकन (re2c-आधारित स्कैनर)
- वाक्यविन्यास विश्लेषण — टोकन → अमूर्त वाक्यविन्यास वृक्ष (Bison व्याकरण)
- संकलन — AST → ऑपकोड ऐरे (op_array)
- निष्पादन — Zend VM ऑपकोड को क्रम से चलाता है
OPcache के बिना, पहले तीनों चरण हर अनुरोध पर दोहराए जाते हैं।
टोकन बनाना
लेक्सर वर्णों को T_VARIABLE, T_ECHO, T_STRING जैसे टोकन में बदलता है। PHP इस चरण को token_get_all() / PhpToken के माध्यम से उपलब्ध कराता है; PHP-CS-Fixer जैसे उपकरण ठीक इसी का उपयोग करते हैं।
<?php
$src = '<?php $x = 1 + 2; echo $x;';
foreach (PhpToken::tokenize($src) as $tok) {
if ($tok->isIgnorable()) continue; // skip whitespace
printf("%-12s %s\n", $tok->getTokenName(), trim($tok->text));
}
?>AST
टोकनों का विश्लेषण करके उन्हें Node के वृक्ष में बदला जाता है — जैसे एक असाइनमेंट Node, जिसके बच्चों में एक चर और एक द्विआधारी-ऑपरेशन अभिव्यक्ति होती है। PHP यह AST आंतरिक रूप से बनाता है और nikic/php-parser PHP कोड में स्थैतिक विश्लेषण के लिए इसका समतुल्य पुनर्निर्मित करता है, जैसा कि PHPStan जैसे उपकरणों में होता है।
<?php
// Conceptual AST for: $x = 1 + 2;
//
// AST_ASSIGN
// ├── AST_VAR ($x)
// └── AST_BINARY_OP (+)
// ├── 1
// └── 2
//
// At compile time PHP folds 1 + 2 into a literal 3
// (constant folding) before generating opcodes.
echo "AST drives opcode generation\n";
?>ऑपकोड
कम्पाइलर एक op_array बनाता है: यह ऑपकोड की एक सपाट सूची होती है। प्रत्येक ऑपकोड की एक ऑपकोड संख्या होती है, जैसे ZEND_ADD, ZEND_ECHO, ZEND_ASSIGN, और उसके साथ अधिकतम दो ऑपरेंड तथा एक परिणाम होता है। इनमें से प्रत्येक संकलित चर (CV), अस्थायी मान (TMP) या स्थिरांक हो सकता है।
<?php
// Opcodes for: $x = 1 + 2; echo $x;
//
// line op operands result
// --- ------------ ----------------- -------
// 1 ADD 1, 2 ~0
// 1 ASSIGN $x, ~0
// 1 ECHO $x
// 1 RETURN 1
//
// ~0 is a temporary; $x is a compiled variable (CV).
echo "op_array is what OPcache stores\n";
?>ऑपकोड का निरीक्षण
आप VLD एक्सटेंशन या OPcache के opcache.opt_debug_level से बनाए गए ऑपकोड प्रदर्शित कर सकते हैं। इससे स्थिरांक-संकलन, मृत-कोड हटाना और नियंत्रण-प्रवाह का JMP/JMPZ ऑपकोड में बदलना दिखाई देता है।
# Dump opcodes with VLD
php -d vld.active=1 -d vld.execute=0 script.php
# Or via OPcache optimizer debug (pre/post optimization)
php -d opcache.opt_debug_level=0x10000 script.php # before opt
php -d opcache.opt_debug_level=0x20000 script.php # after optसंकलित चर (CV)
संकलित कोड में स्थानीय चर हैश-तालिका से खोजे नहीं जाते — कम्पाइलर प्रत्येक चर को एक क्रमांकित CV स्थान देता है। दूसरी बार $x तक पहुँचना प्रतीक-तालिका में खोजने के बजाय ऐरे के किसी इंडेक्स तक पहुँचने जैसा होता है। स्थानीय चरों के तेज़ होने का यह एक प्रमुख कारण है।
<?php
// Each named local gets a fixed CV slot at compile time:
// $a -> CV0 $b -> CV1 $sum -> CV2
function add(int $a, int $b): int {
$sum = $a + $b; // ADD CV0, CV1 -> CV2
return $sum; // RETURN CV2
}
echo add(2, 3) . PHP_EOL;
?>VM का निष्पादन-चक्र
निष्पादक (execute_ex) op_array को क्रम से चलाता है। प्रत्येक ऑपकोड एक हैंडलर फ़ंक्शन से संबद्ध होता है; PHP इस प्रेषण को एक बड़े स्विच, गणना किए गए जंप या संकर रूप में बना सकता है। समर्थ कम्पाइलरों पर डिफ़ॉल्ट संकर रूप सबसे तेज़ होता है। opline पॉइंटर आगे बढ़ता है; नियंत्रण-प्रवाह के लिए JMP ऑपकोड इसे दूसरी जगह ले जाते हैं।
<?php
// if ($n > 0) echo 'pos'; compiles roughly to:
//
// IS_SMALLER 0, $n -> ~T
// JMPZ ~T, ->L1 ; if false, skip
// ECHO 'pos'
// L1:
// RETURN 1
//
// The VM follows opline; JMPZ rewrites it conditionally.
$n = 5;
if ($n > 0) echo "pos\n";
?>OPcache कहाँ आता है
OPcache संकलित op_array को साझा स्मृति में कैश करता है, जिससे बाद के अनुरोधों में शाब्दिक विश्लेषण, वाक्यविन्यास विश्लेषण और संकलन छोड़ दिए जाते हैं। यह एक अनुकूलक चरण भी चलाता है, जिसमें स्थिरांक-संकलन, मृत-कोड हटाना और ऑपकोडों का संलयन शामिल है। प्रत्येक अनुरोध पर VM अभी भी कैश किए गए ऑपकोड को निष्पादित करता है — बाद में JIT इसी हिस्से को तेज़ बनाता है।
फ़ंक्शन कॉल का अतिरिक्त खर्च
कॉल एक नया VM स्टैक फ़्रेम बनाते हैं: पहले INIT_FCALL, फिर प्रत्येक तर्क के लिए SEND_VAL/SEND_VAR, और अंत में DO_FCALL ऑपकोड चलते हैं। यह समझने से स्पष्ट होता है कि बहुत अधिक छोटे फ़ंक्शन कॉल मापने योग्य लागत क्यों पैदा करते हैं और बार-बार चलने वाले लूपों में इनलाइनिंग तथा JIT क्यों महत्वपूर्ण हैं।
<?php
// square($x) compiles to a call sequence:
// INIT_FCALL 'square'
// SEND_VAR $x
// DO_FCALL -> ~R
// ASSIGN $y, ~R
function square(int $x): int { return $x * $x; }
$total = 0;
for ($i = 1; $i <= 5; $i++) {
$total += square($i); // one call sequence per iteration
}
echo $total . PHP_EOL; // 1+4+9+16+25 = 55
?>अनुरोध का समापन
निष्पादन के बाद PHP अनुरोध को समाप्त करता है: सक्रिय चर मुक्त किए जाते हैं, आउटपुट भेजा जाता है और फिर इंजन अपने आवंटक क्षेत्र को रीसेट करता है। साझा-संसाधन-विहीन FPM मॉडल में प्रत्येक अनुरोध साफ़ स्थिति से शुरू होता है — इसलिए एक अनुरोध की घातक त्रुटि दूसरे अनुरोध को दूषित नहीं कर सकती। OPcache के साझा op_array अनुरोधों के बीच बने रहते हैं, लेकिन निष्पादक की स्थिति नहीं रहती।
त्वरित जाँच
पुनः संकलन छोड़ने के लिए OPcache वास्तव में क्या संग्रहीत करता है?
पुनरावलोकन
Zend का प्रसंस्करण-क्रम है: शाब्दिक विश्लेषण → वाक्यविन्यास विश्लेषण → संकलन → निष्पादन। स्रोत टोकन में, फिर AST में और उसके बाद ऑपकोड वाले op_array में बदलता है, जिसे VM का निष्पादक-चक्र चलाता है। स्थानीय चर क्रमांकित CV स्थानों में रखे जाते हैं और कॉल स्टैक फ़्रेम बनाते हैं। OPcache op_array और अनुकूलक चरण को कैश करता है, इसलिए प्रत्येक अनुरोध पर केवल निष्पादन दोहराया जाता है।
एआई शिक्षक के साथ PHP सीखें — निःशुल्क
अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।
- पाठ्यक्रम
- 49
- पाठ
- 195
अक्सर पूछे जाने वाले प्रश्न
क्या “Zend Engine कैसे काम करता है” पाठ निःशुल्क है?
हाँ—“Zend Engine कैसे काम करता है” का पूरा पाठ यहाँ वेब पर निःशुल्क पढ़ा जा सकता है। इंटरैक्टिव अभ्यास (अंतर्निहित कोड संपादक और 24/7 एआई ट्यूटर) करने और PHP Academy पाठ्यक्रम का बाकी हिस्सा अनलॉक करने के लिए CoddyKit PRO लें। PHP Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।
“Zend Engine कैसे काम करता है” में मैं क्या सीखूँगा?
सोर्स से ऑपकोड और फिर निष्पादन तक PHP का अनुक्रम देखें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ PHP Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।
क्या PHP Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?
पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर PHP Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 1वाँ पाठ है।
“Zend Engine कैसे काम करता है” पाठ पूरा करने में कितना समय लगता है?
CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।
क्या मैं इस PHP Academy पाठ में कोड लिख और चला सकता हूँ?
हाँ। हर PHP Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।
इस पाठ्यक्रम के सभी पाठ
- Zend Engine कैसे काम करता है
- मेमोरी प्रबंधन और गार्बेज कलेक्शन
- OPcache और JIT कंपाइलेशन
- C में मूल PHP एक्सटेंशन लिखना