2012-06-05 29 views
6

मेरे पास एक मल्टीप्लेयर सर्वर है जो PHPSockets का उपयोग कर रहा है, और इस प्रकार पूरी तरह से PHP में लिखा गया है।क्या स्क्रिप्ट चल रहा है, तो गतिशील रूप से PHP कोड को फिर से लोड करना संभव है?

वर्तमान में, जब भी मैं PHP सर्वर-स्क्रिप्ट में कोई भी परिवर्तन कर रहा हूं, मुझे स्क्रिप्ट को मारना होगा और फिर इसे फिर से शुरू करना होगा। इसका मतलब है कि ऑनलाइन कोई भी उपयोगकर्ता डिस्कनेक्ट हो जाता है (आमतौर पर कोई समस्या नहीं है क्योंकि इस समय बहुत सारे नहीं हैं)।

अब मैं कस्टम PHP कक्षाओं का उपयोग करने के लिए सर्वर-स्क्रिप्ट को फिर से लिख रहा हूं और चीजों को थोड़ा सा हल करता हूं (आप नहीं जानना चाहते कि यह आज कितना बुरा दिखता है)। आज मैं सोच रहा था: "क्या पूरे स्क्रिप्ट को पुनरारंभ किए बिना php स्रोत में परिवर्तन करना संभव नहीं है?"।

उदाहरण के लिए, मुझे लगता है कि user.php जो वर्ग MyUser होता है और game.php जो वर्ग MyGame शामिल सहित एक main.php फ़ाइल होने पर योजना बना रहा हूँ। अब मान लें कि मैं user.php में परिवर्तन करना चाहता हूं और सर्वर को "पुनः लोड" करना चाहता हूं ताकि user.php में परिवर्तन किसी भी ऑनलाइन उपयोगकर्ताओं को डिस्कनेक्ट किए बिना प्रभावी हो जाएं?

मैंने इसका उत्तर देने वाले अन्य प्रश्नों को खोजने का प्रयास किया, मुझे सबसे नज़दीकी यह सवाल है: Modifying a running script and having it reload without killing it (php), हालांकि ऑनलाइन उपयोगकर्ताओं के डिस्कनेक्शन को हल नहीं किया जा रहा है।

अद्यतन इस के लिए

मेरा अपना समाधान थे:

  1. विशेष occations में फ़ाइल external.php, जो कुछ चर तक पहुंचने और उन्हें तथापि का उपयोग यह चाहते हैं कर सकते हैं शामिल हैं। ऐसा करने पर, मुझे यह सुनिश्चित करना था कि कोड में कोई त्रुटि नहीं थी क्योंकि पूरे सर्वर को क्रैश हो जाएगा यदि मैंने ऐसी विधि तक पहुंचने का प्रयास किया जो मौजूद नहीं था।
  2. पूरी चीज जावा पर लिखें, जिसने मुझे गतिशील वर्ग रीलोडिंग का उपयोग करके प्लगइन सिस्टम जोड़ने की संभावना दी। एक जादू की तरह काम करता है। अलविदा PHP
+0

मैं आम तौर पर एक XML अज्ञात प्रारूप में एक संशोधित "कॉन्फ़िगर" जानकारी संग्रहीत करता हूं जैसे एक्सएमएल फ़ाइल और इसे संशोधित करता हूं। फिर यह कॉन्फ़िगरेशन फ़ाइल को पुनः लोड करने के लिए एक सरल विधि कॉल होना चाहिए और जावा या पायथन में लिखी गई एक संपत्ति (उदाहरण के लिए) आसानी से सर्वर से बाहर भी आसानी से उपयोग कर सकती है। एक प्रोग्राम के स्रोत कोड को गतिशील रूप से बदलने के लिए? यह पहली जगह में एक बुरा विचार की तरह लगता है ... – rdlowrey

+0

मुझे लगता है कि आपको वास्तव में क्या देखना चाहिए, यह है कि क्या आपको वास्तव में प्रति खिलाड़ी एक सॉकेट की आवश्यकता है या यदि आप इसके बजाय गेम को और अधिक राज्य बना सकते हैं। इस प्रकार क्लाइंट से सर्वर पर एक खुला कनेक्शन होने के बजाय, ग्राहक सामान्य वेब अनुरोध भेज सकता है। लेकिन मैं समझता हूं कि शायद कुल पुनर्लेखन का मतलब होगा और इस बिंदु पर कोई विकल्प नहीं है? साथ ही, php "अपरिभाषित" वर्गों का समर्थन नहीं करता है, इसलिए यदि आपने कक्षा "टेस्ट" को पहले ही परिभाषित किया है, तो आप फिर से कक्षा "टेस्ट" को परिभाषित करने के लिए फ़ाइल को फिर से शामिल नहीं कर सकते हैं। –

+3

मुझे लगता है कि सभी ऑनलाइन गेम के बारे में मुझे पता है, जब व्यवस्थापक गेम फ़ाइलों में अपडेट लागू करना चाहता है, तो सर्वर को पुनः लोड किया जाता है और लोग डिस्कनेक्ट हो जाते हैं। शायद यह एक बेहतर संस्करण होना बेहतर होगा जहां सभी उपयोगकर्ता कनेक्ट हों और एक परीक्षण संस्करण जहां केवल आप (या कुछ चुनिंदा लोग) कनेक्ट हों। जब आप परिवर्तनों को लाइव करने के लिए चाहते हैं, तो आप उन्हें ऑनलाइन संस्करण में सहेजते हैं और सर्वर को पुनरारंभ करते हैं।इसका मतलब है कि आपको हर छोटे बदलाव के लिए ऑनलाइन संस्करण को पुनरारंभ करना पड़ेगा जिसे आप बनाना चाहते हैं। – Mike

उत्तर

7

क्या संपूर्ण स्क्रिप्ट को पुनरारंभ किए बिना php स्रोत में परिवर्तन करना संभव नहीं है?

[...]

मैं जो वर्ग MyUser

शामिल आपके मामले में कि user.php सहित एक main.php फ़ाइल होने पर योजना बना रहा हूँ, आप नहीं कर सकते । कक्षाओं को केवल एक चल रही स्क्रिप्ट के भीतर ही परिभाषित किया जा सकता है। उन वर्गों को फिर से परिभाषित करने के लिए आपको स्क्रिप्ट को पुनरारंभ करना होगा।

+0

बहुत धन्यवाद। सिर्फ जिज्ञासा के लिए: क्या एक समारोह को फिर से परिभाषित करना संभव होगा? –

+0

@ साइमन एंड्रेफोर्सबर्ग: आप रनटाइम पर लैम्ब्डा को फिर से परिभाषित कर सकते हैं। प्रोटोटाइप-आधारित प्रोग्रामिंग के बारे में मेरी टिप्पणी में मैं यही बात कर रहा था। – netcoder

2

मैं PHP से बहुत परिचित नहीं हूं लेकिन मुझे लगता है कि स्क्रिप्ट चलाने के लिए एक प्रक्रिया बनाई गई है, ऐसा करने में यह प्रोग्राम चलाने के लिए आवश्यक निर्देशों की प्रतिलिपि बनाता है और सीपीयू पर निष्पादन शुरू करता है, इसके दौरान, यदि आप थे निर्देशों को "अद्यतन" करने के लिए, आपको प्रक्रिया को अंतिम रूप से मारना होगा और इसे पुनरारंभ करना होगा। इसमें आपकी कक्षाओं और फ़ाइलों को एक साथ जोड़ने का एक शानदार तरीका शामिल है लेकिन आखिर में प्रोसेसर की उस जानकारी से अलग होगा जहां से उनकी फाइल संग्रहित की जाती है और जब तक आप प्रक्रिया को पुनरारंभ नहीं करते हैं तब तक यह अंततः अलग होता है।

मुझे किसी भी सिस्टम के बारे में पता नहीं है जिसमें आप कोड बना सकते हैं और सक्रिय रूप से इसे संपादित कर सकते हैं और उस कोड को चलाने के दौरान परिवर्तन देख सकते हैं। अधिकांश सक्रिय प्रोग्रामों को नए स्रोत कोड को पुनः लोड करने के लिए पुनरारंभ करने की आवश्यकता होती है।

+0

किसी चल रहे प्रोग्राम में कोड की गर्म लोडिंग के लिए समर्थन के साथ एक भाषा और रनटाइम के लिए एरलांग देखें। –

+0

यह वीडियो मेरे दिमाग में भी आता है, वास्तव में यह सुनिश्चित नहीं करता कि यह कैसे काम करता है लेकिन यह बहुत अच्छा है: http://www.wimp.com/videogames/ –

+1

@ EmilVikström: यह बहुत अच्छा है, मैंने बस गर्म स्वैपिंग में देखा । यह एक दिलचस्प विचार है लेकिन यह अभी भी एक रीलोड की आवश्यकता है लेकिन मुझे आश्चर्य है कि यह सर्वर के लिए कितना जटिल है। धन्यवाद मैं पढ़ना जारी रखूंगा! (साइमन पर :) हाँ, मैंने देखा है कि, मैं वास्तव में उसके पहले की बात करने गया था, लेकिन मुझे लगता है कि ढांचे की संरचना को चीजों को फिर से चलाने की आवश्यकता होगी और इस प्रकार कोड को फिर से लोड करना होगा या कुछ फैंसी अमूर्त करना होगा वह प्रोग्राम जो उस संपादन को करने के लिए उपयोग किया जा रहा है और इस तरह की अपेक्षाओं को बदलने की संभावना है और इस तरह के बदलाव के लिए पहले से ही कार्यक्रमों की तरह है लेकिन हाँ निश्चित रूप से कमाल है। – richardhsu

-1

मैं पीसी पर खेल के साथ इन चीजों के बारे में पता नहीं है लेकिन आप उन चर

वेब में उपयोग करते हुए पाठ फ़ील्ड या बटन उपयोगकर्ता के लिए अपने डेटाबेस से सभी चर और फिर अद्यतन करने के लिए कोशिश कर सकते हैं AJAX का उपयोग कर रहा है (पेज को रीफ्रेश किए बिना डेटा बदलें)। क्या प्रोग्रामिंग के लिए कोई नहीं है?

+0

AJAX डेटा बदलने के लिए है, मैं कोड बदलना चाहता हूं। –

2

Runkit रनटाइम पर विधियों (अन्य चीज़ों के साथ) को जोड़ने, हटाने और फिर से परिभाषित करने की अनुमति देगा। जबकि आप किसी वर्ग या उसके मौजूदा उदाहरणों के परिभाषित गुणों को नहीं बदल सकते हैं, यह आपको उन वस्तुओं के व्यवहार को बदलने की अनुमति देगा।

मैं इसे स्थायी समाधान, के रूप में अनुशंसा नहीं करता लेकिन यह विकास के दौरान उपयोगी हो सकता है। अंततः आप एक डेटाबेस, Memcache, आदि

0

आप नहीं include फिर से वही class के साथ एक फ़ाइल, लेकिन आप एक array साथ ऐसा कर सकते हैं कर सकते हैं फ़ाइलों के लिए खेल राज्य स्टोर करने के लिए चाहता हूँ। यदि आपको वास्तव में ऐसा करने की ज़रूरत है, तो आप array से class में भी कनवर्ट कर सकते हैं। यह केवल डेटा पर लागू होता है, हालांकि, व्यवहार (विधियों) के लिए नहीं।

+0

हां, 'eval' का उपयोग किये बिना किसी सरणी में कोड लिखना मुश्किल है जो बहुत मूर्ख होगा। :) –

0

आपकी उपयोगकर्ता ऑब्जेक्ट को APC कैश में संग्रहीत करने के बारे में कैसे करें, जबकि आपकी मुख्य स्क्रिप्ट कैश से लोड होती है और हर बार नए ऑपोड के लिए जांचती है।

कैश में कोई फ़ंक्शन शामिल करने के लिए, आपको SuperClosure Class शामिल करना होगा। एक उदाहरण होगा:

if (!apc_exists('area')) { 
    // simple closure 
    // calculates area given length and width 
    $area = new SuperClosure(
    function($length, $width) { 
     return $length * $width; 
    } 
); 
    apc_store('area', $area); 
    echo 'Added closure to cache.'; 
} else { 
    $func = apc_fetch('area'); 
    echo 'Retrieved closure from cache. '; 
    echo 'The area of a 6x5 polygon is: ' . $func(6,5); 
} 

See here for a tutorial on APC

+0

ठीक है, अब आप पूरी तरह से मुझे खो दिया ... एपीसी ?? बस इसे http://www.php.net/manual/en/book.apc.php पर थोड़ा सा चेक करें और यह शक्तिशाली दिखता है। मुझे संदेह है कि मैं इसका उपयोग करूंगा हालांकि, मुझे नहीं लगता कि कई लोग मेरे मामले में इसकी सिफारिश करेंगे .. –

+0

ऐसा लगता है कि केवल डेटा स्टोर करता है, मुझे नहीं पता कि कोड को बदलने के लिए इसका उपयोग कैसे किया जा सकता है? –

+1

यह लिंक देखें: http://devzone.zend.com/1812/using-apc-with-php/ उस भाग पर जाएं जहां यह कहता है कि फ्लाई पर फ़ंक्शंस परिभाषित करता है। – AustinAllover

0

सरल समाधान उपयोग $ MyUser बजाय MyUser

require MyUserV1.php; 
$MyUser = 'MyUserV1'; 
$oldUser = new $MyUser('your name'); 
//Some time after 
require MyUserV2.php; 
$MyUser = 'MyUserV2'; 
$newUser = new $MyUser('your name'); 

हर घोषित स्मृति में वर्ग ठहरने लेकिन जब पिछले MyUserV1 लॉगआउट
आप is_a उपयोग करने के लिए उन्हें एक अमूर्त वर्ग MyUser से विरासत बना सकते हैं अप्रयुक्त बन