क्यों आवश्यक है_ का उपयोग करने के लिए इतना बुरा?


143

बेहतर PHP कोडिंग प्रथाओं के बारे में मैंने जो कुछ भी पढ़ा है वह कहता है कि require_onceगति के कारण इसका उपयोग न करें ।

ऐसा क्यों है?

के रूप में एक ही बात करने के लिए उचित / बेहतर तरीका क्या है require_once? अगर यह मायने रखता है, तो मैं PHP 5 का उपयोग कर रहा हूं।


9
यह प्रश्न अब बहुत पुराना है, और उत्तर अब भी प्रासंगिक रूप से प्रासंगिक हैं। प्रतिभागियों से जवाब का एक अद्यतन सेट देखना बहुत अच्छा होगा :)
प्योरफैन

जवाबों:


108

require_onceऔर include_onceदोनों के लिए आवश्यक है कि सिस्टम पहले से ही शामिल / आवश्यक होने का लॉग रखता है। हर *_onceकॉल का मतलब है कि लॉग की जाँच। तो वहाँ निश्चित रूप से कुछ अतिरिक्त काम किया जा रहा है लेकिन पूरे ऐप की गति को बाधित करने के लिए पर्याप्त है?

... मुझे वास्तव में संदेह है ... तब तक नहीं जब तक आप वास्तव में पुराने हार्डवेयर पर नहीं हैं या इसे बहुत अधिक कर रहे हैं ।

यदि आप कर रहे हैं हजारों काम हैं *_once, तो आप काम को हल्के अंदाज में कर सकते हैं। सरल ऐप के लिए, बस सुनिश्चित करें कि आप केवल शामिल किया है यह एक बार चाहिए पर्याप्त लेकिन आप अभी भी फिर से परिभाषित त्रुटियों हो रही हैं तो आप कुछ इस तरह:

if (!defined('MyIncludeName')) {
    require('MyIncludeName');
    define('MyIncludeName', 1);
}

मैं व्यक्तिगत रूप से *_onceबयानों के साथ रहूँगा लेकिन मूर्खतापूर्ण मिलियन-पास बेंचमार्क पर, आप दोनों के बीच अंतर देख सकते हैं:

                php                  hhvm
if defined      0.18587779998779     0.046600103378296
require_once    1.2219581604004      3.2908599376678

10-100 × के साथ धीमी require_onceऔर यह उत्सुक है कि require_onceप्रतीत होता है में धीमी है hhvm। यदि आप *_onceहजारों बार चल रहे हैं, तो फिर से, यह केवल आपके कोड के लिए प्रासंगिक है ।


<?php // test.php

$LIMIT = 1000000;

$start = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    if (!defined('include.php')) {
        require('include.php');
        define('include.php', 1);
    }

$mid = microtime(true);

for ($i=0; $i<$LIMIT; $i++)
    require_once('include.php');

$end = microtime(true);

printf("if defined\t%s\nrequire_once\t%s\n", $mid-$start, $end-$mid);

<?php // include.php

// do nothing.

29
मुझे संदेह है कि आपकी परिभाषित () विधि अंतर्निहित लुकअप तालिका की तुलना में कोई तेज़ है, लेकिन मैं आपके समग्र बिंदु से सहमत हूं - निश्चित रूप से एक गैर-मुद्दा है ?!
बॉबी जैक

1
मुझे पूरा यकीन है कि आप सही बॉबी हैं लेकिन मैं _once को परिभाषित करने की वकालत नहीं कर रहा हूँ। यह सिर्फ एक विकल्प है। कोड की व्याख्या करने में लगने वाला समय भले ही इसे थोड़ा धीमा कर सकता है, लेकिन कहा कि, मुझे नहीं पता कि आंतरिक विधि कितनी गहन है। यह कोई डुप्लिकेट सुनिश्चित करने के लिए अतिरिक्त काम कर सकता है।
ओली

8
अन्य नकारात्मक पहलू यह है कि APC में कैश शामिल नहीं
है_

3
मैंने सिर्फ दो विधियों का एक बहुत ही बुनियादी परीक्षण किया - मैंने एक फ़ाइल सहित 1,000,000 पुनरावृत्तियों को किया, जो केवल एक निरंतर 'गवाही' को सच करने के लिए परिभाषित करता है। पहले परीक्षण में, मैंने आवश्यकता_ का उपयोग किया था, दूसरे का मैंने उपयोग किया था (यदि परिभाषित ('testinclude')) और परिणाम दिलचस्प थे: आवश्यकता: 0.81639003753662 परिभाषित नहीं: 0.17906713485318 परिभाषित किया गया है 0.63732290267944 माइक्रोसेकंड तेजी से।
ट्रैविस वेस्टन

परिभाषित के साथ मामला और तेज़ होगा क्योंकि आप किसी भी तरह की अतिरिक्त जाँच नहीं कर रहे हैं जैसे कि realpath का उपयोग करना। यह दो चीजों की तुलना नहीं कर रहा है जो वास्तव में समान हैं।
jgmjgm

150

यह धागा मुझे ऐंठता है, क्योंकि पहले से ही "समाधान" पोस्ट किया गया है, और यह, सभी इरादों और उद्देश्यों के लिए गलत है। चलो गणना करें:

  1. PHP में परिभाषित करना वास्तव में महंगा है। आप इसे देख सकते हैं या स्वयं इसका परीक्षण कर सकते हैं, लेकिन PHP में वैश्विक स्थिरांक को परिभाषित करने का एकमात्र कुशल तरीका एक विस्तार है। (वर्ग कांस्टेंट वास्तव में बहुत अच्छे प्रदर्शन के लिहाज से बुद्धिमान होते हैं, लेकिन यह एक महत्वपूर्ण बिंदु है, क्योंकि 2)

  2. यदि आप require_once()उचित रूप से उपयोग कर रहे हैं , अर्थात, कक्षाओं को शामिल करने के लिए, आपको परिभाषित करने की भी आवश्यकता नहीं है; बस जाँच करें कि क्या class_exists('Classname')। यदि आप जिस फ़ाइल को शामिल कर रहे हैं, उसमें कोड है, अर्थात आप इसे प्रक्रियात्मक फैशन में उपयोग कर रहे हैं, तो कोई कारण नहीं है जो require_once()आपके लिए आवश्यक होना चाहिए; हर बार जब आप उस फ़ाइल को शामिल करते हैं जिसे आप सबरूटीन कॉल करने के लिए कहते हैं।

तो कुछ समय के लिए, बहुत से लोगों ने class_exists()अपने समावेशन के लिए विधि का उपयोग किया । मुझे यह पसंद नहीं है क्योंकि यह बहुत ही कम है, लेकिन उनके पास इसका अच्छा कारण require_once()था : PHP के हाल के कुछ संस्करणों से पहले बहुत अक्षम था। लेकिन यह तय हो गया है, और यह मेरा विवाद है कि अतिरिक्त बायोटेक आपको सशर्त, और अतिरिक्त विधि कॉल के लिए संकलित करना होगा, अब तक किसी भी आंतरिक हैशटेबल चेक को ओवरवीज करना होगा।

अब, एक प्रवेश: इस सामान के लिए परीक्षण करना कठिन है, क्योंकि यह निष्पादन के समय के लिए बहुत कम है।

यहां वह प्रश्न है जिसके बारे में आपको सोचना चाहिए: शामिल हैं, सामान्य नियम के रूप में, PHP में महंगे हैं, क्योंकि हर बार जब दुभाषिया हिट करता है तो उसे पार्स मोड में वापस स्विच करना पड़ता है, ऑपकोड उत्पन्न होता है, और फिर वापस कूदता है। यदि आपके पास 100+ शामिल है, तो निश्चित रूप से इसका प्रदर्शन प्रभाव पड़ेगा। आवश्यकता के उपयोग या न करने का कारण_ एक ऐसा महत्वपूर्ण प्रश्न है, क्योंकि यह ओपकोड कैश के लिए जीवन को कठिन बनाता है। इसके लिए एक स्पष्टीकरण यहां पाया जा सकता है, लेकिन यह क्या उबाल है:

  • यदि पार्स समय के दौरान, आप वास्तव में जानते हैं कि उन फ़ाइलों में शामिल हैं जिन्हें आपको अनुरोध के पूरे जीवन के लिए आवश्यक होगा, तो require()वे शुरुआत में और ओपकोड कैश आपके लिए सब कुछ संभाल लेंगे।

  • यदि आप एक opcode कैश नहीं चला रहे हैं, तो आप एक कठिन जगह पर हैं। आपकी सभी फ़ाइलों को सम्मिलित करना एक फ़ाइल में शामिल है (केवल विकास के दौरान ऐसा न करें, केवल उत्पादन में) निश्चित रूप से पार्स समय में मदद कर सकता है, लेकिन यह करने के लिए एक दर्द है, और यह भी, आपको यह जानने की आवश्यकता है कि आप किस दौरान शामिल होंगे निवेदन।

  • ऑटोलैड बहुत सुविधाजनक है, लेकिन धीमा है, इस कारण से कि ऑटोलैड तर्क को हर बार शामिल किया जाना चाहिए। व्यवहार में, मैंने पाया है कि एक अनुरोध के लिए कई विशेष फ़ाइलों को स्वतः सहेजना किसी समस्या का बहुत अधिक कारण नहीं है, लेकिन आपको उन सभी फ़ाइलों का ऑटोलॉगिंग नहीं करना चाहिए जिनकी आपको आवश्यकता होगी।

  • यदि आपके पास शायद 10 शामिल हैं (यह लिफाफे की गणना का एक बहुत ही पीछे का हिस्सा है), तो यह सब लहराता इसके लायक नहीं है: बस अपने डेटाबेस प्रश्नों या कुछ का अनुकूलन करें।


14
यह 4 साल पुराना है और अधिकांश भाग के लिए अब लागू नहीं होता है define(), require_once()और defined()सभी मेरी मशीन पर प्रत्येक के बारे में 1-2 माइक्रोसेकंड लेते हैं।
डैनियल बियर्ड्सले

72
लेकिन उपयोगकर्ता के पेज जल्द ही 2 माइक्रोसेकंड का होगा। एक साल से अधिक पृष्ठ दृश्य, जो उपयोगकर्ता को पूरे 3 सेकंड बचा सकता है! वे उस समय में एक वाणिज्यिक का दसवां हिस्सा देख सकते थे! उपयोगकर्ता के बारे में सोचो। माइक्रोसेकंड बर्बाद मत करो।
एंड्रयू एनस्ले

15
बस हर कोई व्यंग्य से अवगत है, एक माइक्रोसेकंड सेकंड का 1/1000000 है।
एंडी चेस

1
@AndrewEnsley आप बस अपने सभी कटाक्ष के साथ गलत हैं। आप इस तथ्य से अनभिज्ञ हैं कि PHP माइक्रोप्रोसेसरों पर भी चलता है, आपके पीसी पर 1 माइक्रोसेकंड एक माइक्रोप्रोसेसर पर कई मिलीसेकंड है। अब 20 के बारे में क्या फ़ाइलें शामिल हैं, एक बड़ी परियोजना? यह 20 गुना कई मिलीसेकंड देरी से पेश किया गया है, इसलिए हम पहले से ही एक मानव के लिए ध्यान देने योग्य thats तक पहुंच रहे हैं। यदि उस स्क्रिप्ट को अक्सर कहा जाता है, तो यह सिस्टम पर प्रदर्शन समस्याओं का कारण होगा। अनुकूलन एक मजाक नहीं है और पूरी दुनिया आपके पीसी के आसपास नहीं घूम रही है। उपयोग में दस हज़ार सीपीयू हैं।
जॉन

2
@ जॉन। यह अच्छी आत्माओं में बनाया गया एक मजाक था। कोई दुर्भावना नहीं। यदि आपके लिए यह शामिल है कि आप अपने विकल्पों को ऑप्टिमाइज़ करें, तो ठीक है।
एंड्रयू एनस्ले

66

मैं उत्सुक हो गया और एडम बैकस्ट्रॉम के टेक योर यूनिवर्स के लिंक की जाँच की । यह आलेख उन कारणों में से एक का वर्णन करता है जिनके लिए आवश्यकता के बजाय उपयोग किया जाना चाहिए। हालांकि, उनके दावे मेरे विश्लेषण तक नहीं थे। मुझे यह देखने में दिलचस्पी होगी कि मैंने समाधान का दुरुपयोग कहां किया होगा। मैंने तुलना के लिए PHP 5.2.0 का उपयोग किया।

मैंने 100 हेडर फाइलें बनाकर शुरुआत की, जिनमें अन्य हेडर फाइल को शामिल करने के लिए जरूरी_ का उपयोग किया गया था। इनमें से प्रत्येक फाइल कुछ इस तरह दिखती है:

<?php
    // /home/fbarnes/phpperf/hdr0.php
    require_once "../phpperf/common_hdr.php";

?>

मैंने इन्हें त्वरित बैश हैक का उपयोग करके बनाया है:

for i in /home/fbarnes/phpperf/hdr{00..99}.php; do
    echo "<?php
    // $i" > $i
    cat helper.php >> $i;
done

इस तरह मैं आसानी से हेडर फ़ाइलों को शामिल करते हुए आवश्यकता और आवश्यकता के उपयोग के बीच स्वैप कर सकता था। मैंने तब एक ऐप बनाया था। एक सौ फाइलों को लोड करने के लिए। यह देखा:

<?php
    // Load all of the php hdrs that were created previously
    for($i=0; $i < 100; $i++)
    {
        require_once "/home/fbarnes/phpperf/hdr$i.php";
    }

    // Read the /proc file system to get some simple stats
    $pid = getmypid();
    $fp = fopen("/proc/$pid/stat", "r");
    $line = fread($fp, 2048);
    $array = split(" ", $line);

    // Write out the statistics; on RedHat 4.5 with kernel 2.6.9
    // 14 is user jiffies; 15 is system jiffies
    $cntr = 0;
    foreach($array as $elem)
    {
        $cntr++;
        echo "stat[$cntr]: $elem\n";
    }
    fclose($fp);
?>

मैंने आवश्यकता हेडर की आवश्यकता के साथ हेडर के विपरीत काम किया है जो एक हेडर फ़ाइल का उपयोग करता है जैसे कि:

<?php
    // /home/fbarnes/phpperf/h/hdr0.php
    if(!defined('CommonHdr'))
    {
        require "../phpperf/common_hdr.php";
        define('CommonHdr', 1);
    }
?>

जब मुझे यह आवश्यकता के साथ चल रहा था तो मुझे ज्यादा अंतर नहीं मिला। वास्तव में, मेरे शुरुआती परीक्षणों का मतलब यह लग रहा था कि requ_once थोड़ा तेज था, लेकिन मैं जरूरी नहीं मानता कि। मैंने 10000 इनपुट फ़ाइलों के साथ प्रयोग दोहराया। यहाँ मैंने एक सुसंगत अंतर देखा। मैंने कई बार परीक्षण चलाया, परिणाम करीब हैं लेकिन 30_ उपयोगकर्ता की औसत जिफ़ी और 72.6 सिस्टम रिफ़िसेस पर आवश्यकता के अनुरूप उपयोग कर रहे हैं; उपयोग करने के लिए औसत 39.4 उपयोगकर्ता जीफिज और 72.0 सिस्टम जीफिज का उपयोग करने की आवश्यकता होती है। इसलिए, ऐसा प्रतीत होता है कि आवश्यकता _ का उपयोग करके लोड थोड़ा कम है। हालांकि, दीवार घड़ी का समय थोड़ा बढ़ जाता है। औसत पर पूरा करने के लिए 10,000 आवश्यकता_ऑन कॉल का उपयोग 10.15 सेकंड और औसत पर 10,000 कॉल का उपयोग 9.84 सेकंड की आवश्यकता होती है।

इन मतभेदों पर गौर करने के लिए अगला कदम है। मैंने सिस्टम कॉल का विश्लेषण करने के लिए स्ट्रेस का उपयोग किया है जो किए जा रहे हैं।

आवश्यकता से एक फ़ाइल खोलने से पहले निम्नलिखित सिस्टम कॉल किए जाते हैं:

time(NULL)                              = 1223772434
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=88, ...}) = 0
time(NULL)                              = 1223772434
open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

यह आवश्यकता के विपरीत है:

time(NULL)                              = 1223772905
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/fbarnes/phpperf/h", {st_mode=S_IFDIR|0755, st_size=270336, ...}) = 0
lstat64("/home/fbarnes/phpperf/h/hdr0.php", {st_mode=S_IFREG|0644, st_size=146, ...}) = 0
time(NULL)                              = 1223772905
open("/home/fbarnes/phpperf/h/hdr0.php", O_RDONLY) = 3

टेक योर यूनिवर्स का तात्पर्य है कि आवश्यकता होती है_ और अधिक lstat64 कॉल करना चाहिए। हालाँकि, वे दोनों समान संख्या में lstat64 कॉल करते हैं। संभवतः, अंतर यह है कि मैं ऊपर दिए गए कोड को अनुकूलित करने के लिए APC नहीं चला रहा हूं। हालांकि, अगले मैंने पूरे रन के लिए स्ट्रेस के आउटपुट की तुलना की:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out
  190709 strace_1000r.out
  210707 strace_1000ro.out
  401416 total

प्रभावी रूप से लगभग दो और सिस्टम कॉल प्रति हेडर फ़ाइल की आवश्यकता होती है जब आवश्यकता होती है। एक अंतर यह है कि requ_once के पास समय () फ़ंक्शन के लिए एक अतिरिक्त कॉल है:

[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out
strace_1000r.out:20009
strace_1000ro.out:30008

अन्य सिस्टम कॉल getcwd () है:

[fbarnes@myhost phpperf]$ grep -c getcwd strace_1000r.out strace_1000ro.out
strace_1000r.out:5
strace_1000ro.out:10004

इसे इसलिए कहा जाता है क्योंकि मैंने hdrXXX फ़ाइलों में संदर्भित सापेक्ष पथ का निर्णय लिया था। यदि मैं इसे पूर्ण संदर्भ बनाता हूं, तो कोड में किए गए अतिरिक्त समय (NULL) कॉल का एकमात्र अंतर है:

[fbarnes@myhost phpperf]$ wc -l strace_1000r.out strace_1000ro.out
  190705 strace_1000r.out
  200705 strace_1000ro.out
  391410 total
[fbarnes@myhost phpperf]$ grep -c time strace_1000r.out strace_1000ro.out
strace_1000r.out:20008
strace_1000ro.out:30008

इसका अर्थ यह प्रतीत होता है कि आप सापेक्ष पथों के बजाय निरपेक्ष पथों का उपयोग करके सिस्टम कॉल की संख्या को कम कर सकते हैं। इसके बाहर का एकमात्र अंतर समय (NULL) कॉल है जो कि कोड को इंस्ट्रूमेंट करने के लिए उपयोग होने के लिए दिखाई देता है जो कि तेज है।

एक अन्य नोट यह है कि APC ऑप्टिमाइज़ेशन पैकेज में "apc.include_once_override" नाम का एक विकल्प होता है, जो दावा करता है कि यह आवश्यक कॉलों की संख्या को घटाता है जिनमें आवश्यक_ऑनस और शामिल_ऑनस कॉल ( PHP प्रलेखन देखें )।


6
और किसी भी "अनुकूलन" को ऐसे माइनसक्यूल अंतर को देखने के लिए आपको 10,000 बार दौड़ना पड़ता है, यह चिंता करने के लायक भी नहीं है। एक प्रोफाइलर का उपयोग करें और पता करें कि आपके आवेदन में असली अड़चनें कहां हैं। मुझे संदेह है कि यह सवाल अड़चन है।
DGM

1
यह सब क्या मतलब है कि यह बिल्कुल कोई फर्क नहीं पड़ता। तार्किक रूप से आपके लिए जो भी बेहतर काम करता है उसका उपयोग करें।
ब्यूटेल बटुक

वाट जिफ़ीज़ हैं
ओवरकोडर

21

क्या आप हमें इन कोडिंग प्रथाओं के लिए कोई लिंक दे सकते हैं जो इसे टालने के लिए कहते हैं? जहां तक ​​मेरा सवाल है, यह पूरी तरह से गैर-मुद्दा है । मैंने स्वयं स्रोत कोड को नहीं देखा है, लेकिन मुझे लगता है कि इसके बीच एकमात्र अंतर है includeऔर include_onceयह include_onceउस फ़ाइल नाम को एक सरणी में जोड़ता है और हर बार सरणी पर जांच करता है। उस सरणी को क्रमबद्ध रखना आसान होगा, इसलिए उस पर खोज करना हे (लॉग एन) होना चाहिए, और यहां तक ​​कि एक मध्यम-लार्ज एप्लिकेशन में केवल एक दर्जन शामिल होंगे।


एक है, chazzuka.com/blog/?p=163 वे वास्तव में 'नहीं' करते हैं, लेकिन बहुत सी 'महंगी' चीजें जोड़ते हैं। और वास्तव में, सभी शामिल / आवश्यक फाइलें एक आंतरिक सरणी में जोड़ दी जाती हैं (इसे वापस करने के लिए एक फ़ंक्शन होता है), मुझे लगता है कि _once को उस सरणी को लूप करना है और स्ट्रैम्प करना है, जो जोड़ देगा
Uberfuzzy

7

चीजों को करने का एक बेहतर तरीका एक वस्तु-उन्मुख दृष्टिकोण और उपयोग करना है __autoload () का


3
लेकिन
ऑटोलैडिंग

मैं इसे नहीं खरीदता। ऐसी कई परिस्थितियाँ हैं जिनमें OO अन्य प्रतिमानों के रूप में उचित रूप से फिट नहीं है, इसलिए आपको इसे __autoload () के साथ जो भी छोटे लाभ हो सकते हैं, उसे प्राप्त करने के लिए बाध्य नहीं करना चाहिए।
बॉबी जैक

1
आपको लगता है कि ऑटोलैड वास्तव में * _once से अधिक समय लगेगा (यह मानते हुए कि आपको केवल आवश्यकता है कि आपको क्या चाहिए)।
निक

कोई यह नहीं है, कम से कम निश्चित रूप से नहीं, AutoLoad अभी भी किसी भी तरह शामिल किया जाना चाहिए और इसे विफल त्रुटि से पहले PHP के लिए एक अंतिम उपाय है - वास्तविकता PHP में तो वास्तव में सभी स्थानों के माध्यम से potentionally अनावश्यक जांच करता है कि शामिल करने के लिए लागू होगा प्रदर्शन / आवश्यकता होती है और बाद कि यह autoload कहेंगे (यदि कोई परिभाषित) ... पुनश्च: __autoload()हतोत्साहित किया जाता है और यह भविष्य में पदावनत किया जा सकता है, तो आप का उपयोग करना चाहिए spl_autoload_register(...)इन दिनों ... पीएस 2: मुझे गलत नहीं मिलता है, मैं उपयोग autoload कार्यक्षमता कभी कभी करते हैं; )
jave.web

6

यह उस फ़ंक्शन का उपयोग नहीं कर रहा है जो खराब है। समग्र कोड आधार में इसका उपयोग कैसे और कब करना है, यह गलत समझ है। मैं बस थोड़ा और संदर्भ जोड़ दूंगा कि संभवतः गलत धारणा है:

लोगों को यह नहीं सोचना चाहिए कि requirement_once एक धीमा कार्य है। आपको अपने कोड को एक या दूसरे तरीके से शामिल करना होगा। require_once()बनामrequire() की गति मुद्दा नहीं है। यह प्रदर्शन में बाधा उत्पन्न करने वाले प्रदर्शनों के बारे में है जिसके परिणामस्वरूप इसका आँख बंद करके उपयोग किया जा सकता है। यदि व्यापक रूप से संदर्भ के लिए विचार किए बिना उपयोग किया जाता है, तो यह विशाल मेमोरी अपशिष्ट या बेकार कोड हो सकता है।

जो मैंने देखा है वह वास्तव में बहुत बुरा है, जब विशाल अखंड ढांचे का उपयोग होता है require_once() सभी गलत तरीकों से करते हैं, विशेष रूप से एक जटिल वस्तु-उन्मुख (ओओ) वातावरण में।

require_once()हर वर्ग के शीर्ष पर उपयोग करने का उदाहरण लें जैसा कि कई पुस्तकालयों में देखा गया है:

require_once("includes/usergroups.php");
require_once("includes/permissions.php");
require_once("includes/revisions.php");
class User{
  // User functions
}

ऐसा User कक्षा को अन्य सभी तीन वर्गों का उपयोग करने के लिए डिज़ाइन किया गया है। काफी उचित!

लेकिन अब क्या होगा अगर कोई विज़िटर साइट ब्राउज़ कर रहा है और लॉग इन भी नहीं है और फ्रेमवर्क लोड हो रहा है: require_once("includes/user.php");हर एक अनुरोध के लिए।

यह 1 + 3 अनावश्यक वर्गों को शामिल करता है जो कभी भी उस विशेष अनुरोध के दौरान इसका उपयोग नहीं करेगा। इस प्रकार से 5 एमबी या उससे कम के विपरीत 40 एमबी प्रति अनुरोध का उपयोग करके फूला हुआ ढांचा समाप्त होता है।


अन्य तरीकों से इसका दुरुपयोग किया जा सकता है, जब एक वर्ग कई अन्य लोगों द्वारा फिर से उपयोग किया जाता है! मान लें कि आपके पास लगभग 50 कक्षाएं हैं जो helperफ़ंक्शन का उपयोग करती हैं। यह सुनिश्चित करने के लिए कि helpersवे लोड होने पर उन कक्षाओं के लिए उपलब्ध हैं, आपको मिलता है:

require_once("includes/helpers.php");
class MyClass{
  // Helper::functions(); // etc..
}

यहाँ कुछ भी गलत नहीं है। हालांकि अगर एक पेज अनुरोध 15 समान वर्गों को शामिल करने के लिए होता है। आप require_once15 बार या एक अच्छे दृश्य के लिए दौड़ रहे हैं :

require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");
require_once("includes/helpers.php");

आवश्यकता से अधिक उन पंक्तियों को पार्स करने के लिए, 14 बार उस फ़ंक्शन को चलाने के लिए आवश्यकता_ऑनसे () का उपयोग तकनीकी रूप से प्रदर्शन को प्रभावित करता है। इस तरह की समस्या के साथ सिर्फ 10 अन्य अत्यधिक उपयोग किए जाने वाले वर्गों के साथ, यह इस तरह के निरर्थक दोहराव वाले कोड की 100+ लाइनों के लिए जिम्मेदार हो सकता है।

इसके साथ, यह संभवतः require("includes/helpers.php");आपके एप्लिकेशन या फ्रेमवर्क के बूटस्ट्रैप का उपयोग करने के बजाय इसके लायक है । लेकिन जब से सब कुछ सापेक्ष है, यह सब निर्भर करता है कि helpersवर्ग की भार बनाम उपयोग आवृत्ति 15-100 लाइनों की बचत के लायक है या नहीं require_once()। लेकिन अगर helpersकिसी भी अनुरोध पर फ़ाइल का उपयोग नहीं करने की संभावना कोई नहीं है, तो requireनिश्चित रूप से इसके बजाय आपके मुख्य वर्ग में होना चाहिए। require_onceप्रत्येक वर्ग में अलग-अलग होने से संसाधनों की बर्बादी होती है।


require_onceसमारोह उपयोगी है जब आवश्यक है, लेकिन के रूप में एक अखंड समाधान सभी वर्गों लोड करने के लिए हर जगह उपयोग करने के लिए यह नहीं माना जाना चाहिए।


5

PEAR2 विकी (जब यह अस्तित्व में था) सभी आवश्यकता को छोड़ने के लिए अच्छे कारणों को सूचीबद्ध करता था / जिसमें ऑटोलैड आईएनजी के पक्ष में निर्देश शामिल थे , कम से कम लाइब्रेरी कोड के लिए। जब आप फ़ार जैसे वैकल्पिक पैकेजिंग मॉडल का उपयोग करते हैं, तो आप कठोर निर्देशिका संरचनाओं से जुड़ जाते हैं क्षितिज पर होते हैं हैं।

अद्यतन: विकी के वेब संग्रहीत संस्करण के रूप में आंखें बदसूरत है, मैंने नीचे सबसे सम्मोहक कारणों की नकल की है:

  • एक (PEAR) पैकेज का उपयोग करने के लिए शामिल_पाठ आवश्यक है। यह एक व्यापक आवेदन कोड संशोधन के बिना एक फ़ार संग्रह में PEAR पैकेज को स्थानांतरित करने के लिए आवश्यक कक्षाओं से युक्त एक एकल फ़ाइल बनाने के लिए, अपने ही__पाठ के साथ एक अन्य आवेदन के भीतर एक पीईएआर पैकेज को बंडल करना मुश्किल बनाता है।
  • जब शीर्ष-स्तर के requ_once को सशर्त requ_once के साथ मिलाया जाता है, तो यह कोड में परिणाम कर सकता है जो APC जैसे opcode कैश द्वारा उपलब्ध नहीं है, जिसे PHP 6 के साथ बंडल किया जाएगा।
  • रिश्तेदार की आवश्यकता है। किसी को भी पहले से ही सही मूल्य तक सेट करने के लिए शामिल करना आवश्यक है, जिससे उचित पैकेज के बिना पैकेज का उपयोग करना असंभव हो जाता है।

5

*_once()कार्यों स्टेट की गई फ़ाइल को सुनिश्चित करने के लिए प्रत्येक पैरेंट डायरेक्टरी को करता है, जो पहले से ही शामिल नहीं है। यह मंदी के कारण का हिस्सा है।

मैं बेंचमार्किंग के लिए घेराबंदी जैसे उपकरण का उपयोग करने की सलाह देता हूं । आप सभी सुझाई गई विधियों को आज़मा सकते हैं और प्रतिक्रिया समय की तुलना कर सकते हैं।

अधिक पर require_once()पर है टेक आपका यूनिवर्स


लेख के लिए सूचक के लिए धन्यवाद। requirement_once () डबल-फ़ाइलों सहित एक अच्छा सुरक्षा बेल्ट है, और हम इसका उपयोग करना जारी रखेंगे, लेकिन इसे साफ करने में सक्षम होना अच्छा है।
एंडी लेस्टर

2

यहां तक कि अगर require_onceऔर include_once कर रहे हैं धीमी गति से requireऔर include(या जो भी विकल्प मौजूद हो सकता है), हम यहाँ सूक्ष्म अनुकूलन के सबसे छोटे स्तर के बारे में बात कर रहे हैं। आपका समय बहुत ही बेहतर ढंग से व्यतीत होता है जो खराब लिखित लूप या डेटाबेस क्वेरी की तरह कुछ के बारे में चिंता करने से बेहतर होता है require_once

अब, कोई यह कहते हुए तर्क दे सकता है कि require_onceखराब कोडिंग प्रथाओं के लिए अनुमति देता है क्योंकि आपको अपने स्वच्छ और व्यवस्थित रखने पर ध्यान देने की आवश्यकता नहीं है, लेकिन इसका फ़ंक्शन के साथ कुछ भी नहीं करना है और विशेष रूप से इसकी गति नहीं है।

जाहिर है, कोड की स्वच्छता और रखरखाव में आसानी के लिए ऑटोलॉडिंग बेहतर है, लेकिन मैं यह स्पष्ट करना चाहता हूं कि इसका गति से कोई लेना-देना नहीं है ।


0

आप परीक्षण करते हैं, इसमें शामिल हैं, ओली का विकल्प और __autoload (); और एपीसी स्थापित की तरह कुछ के साथ यह परीक्षण ।

मुझे संदेह है कि निरंतर उपयोग से चीजों को गति मिलेगी।


0

हां, यह सादे ओल की आवश्यकता () से थोड़ा अधिक महंगा है। मुझे लगता है कि बिंदु यह है कि यदि आप अपने कोड को डुप्लिकेट नहीं करने के लिए पर्याप्त रूप से व्यवस्थित रख सकते हैं, तो * _once () फ़ंक्शन का उपयोग न करें, क्योंकि यह आपको कुछ चक्रों को बचाएगा।

लेकिन _once () फ़ंक्शंस का उपयोग करना आपके एप्लिकेशन को मारने वाला नहीं है। मूल रूप से, बस इसे एक बहाने के रूप में उपयोग न करें जिसमें आपके शामिल होने का आयोजन न हो । कुछ मामलों में, इसका उपयोग करना अभी भी अपरिहार्य है, और यह कोई बड़ी बात नहीं है।


-2

मुझे लगता है कि PEAR डॉक्यूमेंटेशन में, आवश्यकता के लिए एक सिफारिश है, requirement_once, इसमें शामिल हैं और __ce। मैं उस गाइडलाइन का पालन करता हूं। आपका आवेदन अधिक स्पष्ट होगा।


कुछ संदर्भ क्रम में होंगे।
पीटर मॉर्टेंसन

-3

इसका गति से कोई लेना-देना नहीं है। यह शालीनता से असफल होने के बारे में है।

यदि आवश्यक हो तो_नहीं () विफल हो जाता है, आपकी स्क्रिप्ट हो जाती है। और कुछ भी संसाधित नहीं है। यदि आप अपनी स्क्रिप्ट का उपयोग करते हैं, तो आप अपनी स्क्रिप्ट के बाकी हिस्सों में विफल हो जाएंगे।


1
जरुरी नहीं। आप वास्तव में उपयोगकर्ता को एक अच्छा त्रुटि पृष्ठ देने के लिए एक त्रुटि हैंडलर या शटडाउन हैंडलर पर हुक कर सकते हैं (हालांकि लोग शायद ही कभी करते हैं)। एक डेवलपर के रूप में, मैं बहुत बल्कि चीजों को तुरंत त्रुटि देगा।
एडवर्ड जेड यांग

1
या, जैसा कि मामला हो सकता है, सुशोभित रूप से विफल नहीं हो रहा है - अगर कुछ महत्वपूर्ण फ़ाइल की आवश्यकता नहीं है () ठीक से, यह सिर्फ एक अच्छा विचार है कि छोड़ देना और रोक देना। लेकिन इसके लिए बनाम शामिल करने की आवश्यकता होती है, जबकि मुझे लगता है कि प्रश्न आवश्यकता पर अधिक ध्यान देने की आवश्यकता है।
होबोबेन

-4

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

आपको पता होना चाहिए कि क्या आपको एक फ़ाइल शामिल करने की आवश्यकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.