Hybrid PHP का उभार: PHP के साथ Go और Rust का संयोजन
(yekdeveloper.com)- हाल के समय में PHP monolithic architecture के भीतर Go और Rust को extension languages के रूप में एकीकृत करने वाला hybrid तरीका ध्यान आकर्षित कर रहा है
- पहले Go microservices और PHP 8.3 monolith के संयोजन से productivity और high performance के बीच संतुलन हासिल किया जाता था
- Pareto principle (80% traffic, 20% API पर केंद्रित) के अनुसार hotspot endpoints को optimize करना ज़रूरी था, और पहले इसके लिए caching तथा Go services को अलग करना जैसे तरीके अपनाए जाते थे, लेकिन इससे जटिलता बढ़ती थी
- हाल में PHP ecosystem के विकास से FFI, Rust extensions, Go extensions (FrankenPHP) जैसी तकनीकें सामने आई हैं, जिनसे monolith के भीतर ही performance को काफ़ी बढ़ाया जा सकता है
- Rust extensions memory safety और speed दोनों देती हैं, और FrankenPHP worker mode तथा Go-based extensions के ज़रिए अधिकतम 4x से ज़्यादा performance improvement दिखाता है
- पूरे सिस्टम को Go/Rust में rewrite करने की लागत और जोखिम से बचते हुए, hybrid PHP approach के ज़रिए productivity और speed दोनों हासिल की जा सकती हैं
पृष्ठभूमि और मौजूदा architecture
- पहले DDD monolithic application (mother) को केंद्र में रखकर, कुछ खास फीचर्स को optimize करने के लिए अलग से Go-based microservices (children) विकसित की जाती थीं
- Go microservices high-performance traffic handling संभालती थीं, जबकि PHP 8.3 monolith छोटी backend टीमों के लिए तेज़ feature development और deployment reliability प्रदान करता था
- यह संरचना speed, stability और productivity—तीनों को साथ पाने के लिए एक संतुलित बिंदु देती थी
performance bottlenecks और पुराने response तरीके
- अक्सर Pareto principle देखा जाता है, जिसमें 80% traffic, 20% API endpoints पर केंद्रित होता है
- performance के लिहाज़ से सबसे महत्वपूर्ण इस 20% हिस्से के लिए optimized code लिखना, caching layers जोड़ना, Go microservices में अलग करना जैसे कई तरीके अपनाए गए
- लेकिन complexity और operations overhead के मामले में इनकी सीमाएँ थीं
आधुनिक PHP ecosystem के hybrid options
- अब PHP monolith के भीतर सीधे performance improve करने वाली तकनीकें बढ़ रही हैं
-
1. FFI (Foreign Function Interface)
- PHP के FFI feature से PHP के भीतर से C code को सीधे call किया जा सकता है
- system-level या performance-critical logic भी PHP project के भीतर implement किया जा सकता है
- हालांकि, context switching cost को ध्यान में रखते हुए इसे केवल उपयुक्त स्थितियों में इस्तेमाल करने की सलाह दी जाती है
-
2. Rust-based extensions
- Rust (या Zig) से PHP extensions विकसित किए जा सकते हैं
- high-load processing वाले हिस्सों को memory safety और compiled performance वाले Rust extensions में offload करके, reliability और high speed दोनों हासिल की जा सकती हैं
-
3. Go-based extensions: FrankenPHP
- हाल में FrankenPHP पर switch करने के बाद worker mode में चलाने पर, पहले की तुलना में 4x से अधिक तेज़ performance देखी गई
- हाल की release के साथ Go में PHP extensions लिखना भी संभव हो गया है
- इससे Go की API performance को सीधे PHP monolith के भीतर इस्तेमाल किया जा सकता है, और language split के बिना productivity और speed को जोड़ा जा सकता है
पूरे Go या Rust में पूर्ण migration न करने के कारण
- पूरे rewrite की लागत और जोखिम बहुत अधिक हैं
- पहले से बड़े और स्थिर application को पूरी तरह Go या Rust में बदलना जोखिम और resource consumption—दोनों के लिहाज़ से भारी है
- PHP के अपने मजबूत पक्ष अब भी मौजूद हैं
- ज़्यादातर कामों में PHP की तेज़ development speed, अनुकूल ecosystem और पर्याप्त performance अब भी प्रतिस्पर्धी हैं
- केवल वे हिस्से जहाँ वास्तविक performance limits की ज़रूरत है, वहाँ Go और Rust का hybrid इस्तेमाल करके पूरे migration की आवश्यकता से बचा जा सकता है
निष्कर्ष: hybrid PHP का महत्व
- आधुनिक PHP ecosystem तेज़ development productivity के साथ high-performance (C, Rust, Go) extensions integration के सभी विकल्प देता है
- ऐसे hybrid ढाँचे से speed और productivity दोनों हासिल की जा सकती हैं
- PHP-केंद्रित development को बनाए रखते हुए, ज़रूरत पड़ने पर चुनिंदा language extensions जोड़ने वाला एक नया architectural paradigm सामने आता है
5 टिप्पणियां
लगता है जैसे JavaScript जिस तरह बदल रहा है, यह भी वैसा ही होता जा रहा है।
Rust को Node.js के साथ हो तो समझ आता है;; लेकिन मुझे PHP में
$जैसी चीज़ें बार-बार इस्तेमाल होने की वजह से code टाइप करना असुविधाजनक लगता है, तो जो लोग इसे अच्छी तरह इस्तेमाल करते हैं क्या उन्हें ज़्यादा असुविधा महसूस नहीं होती?असुविधा महसूस हो तब भी, इस्तेमाल करते-करते क्या हम जल्दी अभ्यस्त नहीं हो जाते?
इंसान अनुकूलन करने वाला जीव है।
मुझे PHP के variable/function कॉन्सेप्ट से असहजता महसूस हुई हो तो हुई हो, लेकिन
$नोटेशन से मुझे कभी भी ज़रा भी असहजता महसूस नहीं हुई।यह कहना कि dollar sign की वजह से इसे इस्तेमाल नहीं कर सकते, ~~dollar sign इस्तेमाल करने वाले लोग बहुत पैसा कमाते हैं, US dollar नहीं बल्कि Zimbabwe dollar है इसलिए ज़्यादा नहीं कमाते~~ — क्या ये सब बस मज़ाक में कही जाने वाली बातें नहीं थीं...
Hacker News राय
मुझे generic frameworks (Spring, Laravel, Phoenix आदि) से धीरे-धीरे चिढ़ होने लगी है। शुरू में वे सचमुच बहुत productive लगते हैं, लेकिन legacy projects में बार-बार वही समस्याएँ दोहराई जाती हैं। हर project का infra environment और business context अलग होता है, इसलिए framework के recommended तरीके पर ही सब कुछ नहीं किया जा सकता; नतीजा यह होता है कि जगह-जगह extra patches और dependency hacks बढ़ते जाते हैं। जब नई language या version पर upgrade करने की कोशिश करते हैं, तो ये सारे customized हिस्से टूट जाते हैं। आखिर में कोई update नहीं करता, और जब infra पर चलाना ही संभव नहीं रह जाता, तब रोते-धोते बड़ी migration करनी पड़ती है। कई libraries को जोड़कर अपनी abstraction बनाना ज़्यादा समय ले सकता है, लेकिन इससे हिस्सों को लचीले ढंग से upgrade किया जा सकता है और दिशा जल्दी बदली जा सकती है। मुझे लगता है कि Go ecosystem इस मामले में ideal है। शुरुआत में अजीब लगा था, लेकिन अब मुझे यही तरीका ज़्यादा पसंद है।
web frameworks के बारे में मेरा एहसास यही है कि “शुरू में बहुत अच्छे लगते हैं, फिर एक समय बाद बोझ बन जाते हैं।” जब simple app बनानी होती है, तब Rails जैसे “15 मिनट में blog बनाओ” वाले अनुभव जादू जैसे लगते हैं, लेकिन complexity बढ़ते ही framework खुद रुकावट बन जाता है। मेरे लिए Express + Node.js या Vert.x + Java जैसे “mid-level” HTTP setups ज़्यादा आरामदायक हैं।
Python में microframeworks (Flask जैसी) और macroframeworks (Django) के रूप में बाँटकर देखा जा सकता है। मैं हमेशा Django चुनता हूँ। Flask लगभग कुछ भी recommend नहीं करता, इसलिए हर project एक नया snowflake बन जाता है। auth, templates, cookies, email वगैरह के लिए N तरह के options में से क्या चुना जाए, इस पर decision fatigue हो जाती है। खासतौर पर ऐसी libraries अक्सर एक ही developer द्वारा maintain की जाती हैं, इसलिए maintenance और security quality भी असमान रहती है। इसके उलट Django में ज़्यादातर projects का ढाँचा मिलता-जुलता होता है, और लगभग सभी basic features तुरंत मिल जाते हैं। मुझे extension libraries तभी चाहिए होती हैं जब requirements वाकई special हों। क्योंकि बहुत कुछ सीधे maintain और verify किया गया होता है, मुझे लगता है code reliability और security भी बेहतर रहती है।
Go में बड़े frameworks कम होने की एक वजह यह है कि language का type system अभी भी काफी अधूरा है। ऐसी complex libraries बनाना मुश्किल है जो एक-दूसरे के साथ अच्छे से fit हों। मैंने Go के लिए अपना database toolkit पहली बार तब बनाया, जब 9 साल इंतज़ार करने के बाद generics इस्तेमाल करना संभव हुआ। वह सफल रहा, लेकिन फिर भी महसूस हुआ कि पहले Java में ऐसा करना बेहतर था। अगर result types को दूसरे generic types पर map/filter/reduce किया जा सकता, तो दुनिया ही अलग होती। अगर सिर्फ union types का support मिल जाए, तो
anytype की ज़रूरत ही न पड़े। सिर्फ overloading support भी मिल जाए तो code काफी साफ हो जाएगा; Go type system को अभी और विकसित होना है।मेरे domain में सिर्फ Go और Rust ही काम के हैं। strong-opinionated framework culture मुझे suit नहीं करता। मुझे लगता है Rails, Laravel, Django relational DB CRUD use cases में, जहाँ सब कुछ स्पष्ट हो, वहाँ बेहतरीन हैं।
पिछले 5 सालों से मैं सिर्फ PSR (Php Standards Recommendation) compatible components का इस्तेमाल कर रहा हूँ, frameworks का बिल्कुल नहीं। कारण यह है कि बड़े frameworks लंबे समय में फिट नहीं बैठते। उनमें constraints बहुत होते हैं, और maintenance व updates बहुत कठिन हो जाते हैं। चाहे कंपनी का large-scale project हो या personal service, मुझे PSR component-centric architecture बेहतर लगती है।
समझ सकता हूँ कि जब codebase बहुत बड़ा हो और पूरा rewrite करना संभव न हो, तब hybrid approach (C, Rust, Go जैसी performance languages के साथ PHP) का मतलब हो सकता है। लेकिन अगर इसकी मजबूरी न हो, तो मेरे अनुभव में C# API development speed और runtime performance दोनों दे देता है। मुझे शायद ही कभी C++ या Rust तक जाने की ज़रूरत पड़ी है। PHP भी अच्छा है, लेकिन अभी भी typed arrays जैसी चीज़ें नहीं हैं। उदाहरण के लिए, date array में string आ जाए तो भी language उसे reject नहीं करती।
मैंने C# लंबे समय तक इस्तेमाल किया है और कई web/API frameworks का अनुभव है। अगर PHP को थोड़ा गहराई से देखें, तो web development के लिए इसमें built-in functions की भरमार होना बहुत अच्छा लगता है। कमियाँ हैं, लेकिन जब कुछ जल्दी बनाना हो, तो मेरे हिसाब से PHP जीतता है।
यह सही है कि PHP arrays में गलत type (जैसे date array में string) भी स्वीकार कर लेता है। कभी-कभी अजीब behavior या bugs निकल आते हैं। हाल ही में
json_decode()से decode करते समय मुझे ऐसा bug मिला, जहाँ numeric keysintबन रही थीं और बाकीstring, जिससे key types mix हो गए। ऐसी कोने-कोने की बातें अजीब लग सकती हैं, लेकिन फिर भी PHP खुद में एक बेहद आकर्षक Frankenstein language है।असल में static analyzer इस्तेमाल करें तो ऐसे type errors रुक जाते हैं। PHP में generics support भी जल्द आने की अच्छी संभावना है। इससे जुड़ी जानकारी thephp.foundation ब्लॉग में देख सकते हैं।
मैं ही इस लेख का लेखक हूँ, पढ़ने के लिए धन्यवाद। असल में पूरा rewrite करने की ज़रूरत नहीं है; अगर PHP को
swooleयाfrankenphpजैसे worker-based runtimes पर चलाया जाए, तो Node-level performance मिल सकती है। typed arrays और generics जैसी समस्याओं के लिएphpstanजैसे static analyzers support देते हैं, और type annotations का उपयोग करने से type safety काफी बेहतर हो सकती है।VB6 support बंद होने के बाद से मैंने तय कर लिया कि Microsoft languages का इस्तेमाल नहीं करूँगा। open source languages ही मानसिक शांति के लिए अच्छा विकल्प हैं।
जब मैं {{company}} में शामिल हुआ था, तब पूरी कंपनी का environment PHP 5.4 पर था, और उस समय PHP को लेकर नापसंदगी बहुत थी। लेकिन modern PHP देखने के बाद लगता है कि ठीक उसी समय, जब हम PHP से बाहर निकलने के आखिरी चरण में हैं, यह migration उल्टा “इस समय तो पीछे जाना” जैसा लग रहा है। लोग अभी भी PHP को 5.x दौर से judge करते हैं, जबकि अब यह पूरी तरह अलग है।
मैं इसे थोड़ा अलग तरह से देखता हूँ। job market में आज भी PHP को लेकर एक perception है—अच्छा या बुरा—और इससे strong developers को hire करने में सीमा आती है। तकनीकी रूप से PHP पहले जितना बुरा न भी रहा हो, फिर भी company branding के नज़रिए से PHP से बाहर निकलना अब भी मायने रखता है।
“PHP अब awesome है” इस बात से मैं सहमत नहीं हूँ। निस्संदेह यह बेहतर हुआ है, लेकिन awesome कहना कुछ ज़्यादा है।
PHP लगातार बेहतर हो रहा है। मुझे लगता है जल्द ही इसे और गहराई से देखना चाहिए।
हमने भी 4 साल पहले बिल्कुल यही दुविधा झेली थी, और आखिरकार PHP 8 पर upgrade करके उसी पर बने रहे। हमारी team के लिए पिछले कुछ सालों में वह फैसला अच्छा साबित हुआ।
Pasir, frankenphp जैसा है लेकिन Rust-based है। बहुत promising है, लेकिन अभी development के शुरुआती चरण में है।
Pasir github Pasir, Zend API bindings के Rust translation का उपयोग करता है।
Zend API Rust bindings
ngx-phpजैसा एक दिलचस्प प्रयोग भी है, जिसमें nginx binary के अंदर Zend API के ज़रिए PHP embed किया गया है।ngx-php github
workermanasio hybrid backend का उपयोग करके बहुत तेज runtime बनाता है।workerman github
जानना चाहूँगा कि Pasir, frankenphp आदि existing PHP modules को भी support करते हैं या नहीं।
सिफारिश के लिए धन्यवाद, सचमुच बहुत शानदार लग रहा है। लेकिन जैसा आपने कहा, मैं भी सहमत हूँ कि यह अभी production स्तर से काफी दूर है। हमने आखिरकार
frankenphpचुना, जिसे php foundation support करता है।debugging और maintenance की complexity को अक्सर कम आँका जाता है। अगर विकल्प हो, तो मेरे हिसाब से ऐसे संयोजन से बचना बेहतर है।
frankenphpचुना है; अगर debugging इसके साथ ज़्यादा कठिन हो सकती है, तो कृपया थोड़ा specific बताइए कि क्यों।मैंने भी अपना app PHP से Go में rewrite किया, और वह कंपनी के लिए सफल investment साबित हुआ। 20,000 lines का PHP code घटकर 4,000 lines के Go code में आ गया, और efficiency भी काफी बढ़ी। अगर आपकी company PHP shop है, तो मैं ज़ोर देकर कहूँगा कि बड़े पैमाने पर rewrite की योजना बनाएँ, tests जोड़ें (Go में यह आसान है), और आगे बढ़ें। मेरे हिसाब से Rust/PHP या Go/PHP की तरह कई languages मिलाकर maintenance का दर्द झेलने से यह बेहतर है।
जिज्ञासा है कि PHP से Go में जाते हुए lines of code इतनी कैसे घट गईं? मुझे Go वैसे भी काफी verbose language लगती है। मेरे अनुभव में PHP बीच में है, Haskell सबसे compact है, और Java/Go तो error handling वगैरह के कारण और लंबे हो जाते हैं।
PHP से Go में rewrite करते हुए code 5 गुना कम हो गया, यह मुझे समझ नहीं आता। PHP में तरह-तरह की shorthand syntax है, जबकि Go में ऐसी चीज़ें कम हैं।
rewrite के बाद performance और efficiency बेहतर हुई, इसमें हमेशा यह अहम सवाल होता है कि “यह language की वजह से हुआ, या नई architecture improvements की वजह से?”
मुझे लगा था Go rewrite करते समय
if err != nilpattern से code उल्टा 10 गुना बढ़ जाएगा। मैंने Python rewrite का अनुभव किया है, और Python में भी code काफी verbose हो जाता है, जबकि dependency injection जैसे patterns testing को झंझटभरा बनाते हैं।मैं हर हालत में rewrite की सलाह नहीं देता (हालाँकि मैंने दो successful rewrites पूरे किए हैं, फिर भी शायद खुद नहीं चुनूँगा)। आजकल PHP runtimes सचमुच बहुत तेज हो गए हैं, इसलिए उन्हें आज़माना भी काफ़ी worthwhile है। खासतौर पर
swooleजैसी job caching का पूरा फायदा लिया जाए, तो कभी-कभी Go जितनी speed मिलती है (benchmark देखना बेहतर रहेगा)।कभी-कभी मुझे लगता है कि हमें सचमुच basics पर लौटना चाहिए: pixels, data, latency/bandwidth। आखिर web भी “network resources के भीतर, इंसानी आँख को नज़र आने लायक तेज़ी से सही pixels render करने” की optimization problem ही है। “user आगे कौन से pixels देखेगा?”, “उन्हें render करने के लिए कौन सा data चाहिए?”, “जो data आगे काम आ सकता है उसे पहले prefetch करें?” — मुझे लगता है हमें इसी सोच से काम लेना चाहिए।
मैं alumina-ui को WASM के लिए
eguiमें बना रहा हूँ, और इसमें HTML, JavaScript, CSS जैसी जटिल web knowledge के बिना, बस browser-fit size का एक canvas देना होता है और सीधे WebGL से render करना होता है। अपनी पसंद की language में तेज़, GL-accelerated graphics निकाल पाना बहुत सुविधाजनक है। ऐसी abstraction की वजह से मुझे WASM/WebGL बहुत पसंद है।सिर्फ उन pixels पर ध्यान देना जो user देखता है, बहुत संकीर्ण नज़रिया है। software projects में सिर्फ immediate UX ही नहीं, development time को भी optimize करना पड़ता है। पहला screen दिखने में लगने वाला delay और actual development effort कभी भी सीधे proportional नहीं होते।
FrankenPHP काफ़ी दिलचस्प दिखता है, लेकिन व्यवहार में थोड़ा अजीब है। कोई भी PHP को modules के बिना इस्तेमाल नहीं करता, लेकिन FrankenPHP किन PHP modules को support करता है, इसकी साफ़ सूची नहीं दिखती, और यह भी स्पष्ट नहीं कि मैं अपने मनचाहे extra modules build करके जोड़ सकता हूँ या नहीं। यह Caddy के साथ काफ़ी tightly coupled है, जबकि मैं इस web server से परिचित नहीं हूँ और nginx को ज़्यादा पसंद करता हूँ। guide न होने के कारण मुझे यह भी नहीं पता कि nginx में इसे
php-fpmके replacement की तरह इस्तेमाल किया जा सकता है या नहीं। ऊपर से Caddy या FrankenPHP की Docker images मानो सिर्फ Let's Encrypt certificates को ध्यान में रखकर बनाई गई हैं, इसलिए खुद SSL configure करना या सिर्फ HTTP पर चलाना बहुत unintuitive लगता है।PHP modules वाली समस्या आमतौर पर Dockerfile में खुद build करके सुलझाई जाती है। उदाहरण के तौर पर
pgsqlmodule जोड़ना हो तोaptसे dependencies install करें,docker-php-ext-installसे module install करें, और अंत में dependencies हटा/clean कर दें। HTTP configuration भी Caddyfile में सीधे port 80 खोलकर की जा सकती है।static build में default रूप से PHP के दर्जनों प्रमुख modules शामिल होते हैं। modules की विस्तृत सूची और build scripts frankenphp build-static.sh में देखी जा सकती हैं।
मैं जानना चाहता हूँ कि किस तरह के workloads में C/Rust/Go जैसे language extensions सचमुच ज़रूरी हो जाते हैं। मैं समझता हूँ कि ऐसे cases मौजूद हैं, लेकिन stack में इतनी complexity क्यों जोड़नी चाहिए, और क्या इसे किसी और तरीके से हल नहीं किया जा सकता — यह और जानना चाहूँगा।
PHP के बारे में मेरी सबसे नापसंद बात यह है कि हर HTTP request पर पूरी application फिर से bootstrap होती है, autoloading और configuration फिर से evaluate होते हैं। हाँ, caches वगैरह मौजूद हैं, लेकिन Go की तरह हमेशा engine चलने वाले model की तुलना में यह फिर भी अटपटा लगता है।
reactphp.org
php.net ev module
pecl-event
workerman.net
frankenphp worker docs
मेरे लिए तो यही PHP का सबसे बड़ा फ़ायदा है। इससे scale-out बहुत आसान हो जाता है।
मुझे तो यह structure उल्टा अच्छा लगता है। इसमें inherently state बहुत कम रहती है (कम से कम एक हद तक)।
तुम सही कह रहे हो, यह तरीका सचमुच बहुत खराब है। खासतौर पर जब PHP को खुद template language की तरह इस्तेमाल किया जाता है, तब और भी बुरा लगता है। इसे ठीक करने की कोशिश करने वाले custom template engines या persistent runtimes भी आखिरकार सिर्फ “सुअर पर लिपस्टिक” लगाने जैसा है। बेहतर होता कि शुरू से ही ऐसी language चुनी जाती जिसका नाम Personal HomePage न रहा हो।