सिम्फनी 2 में बंडल करने के लिए फाइल रिलेटिव एक्सेस करना


83

एक Symfony2 ऐप के रूटिंग कॉन्फ़िगरेशन में, मैं इस तरह से एक फ़ाइल का उल्लेख कर सकता हूं:

somepage:
    prefix: someprefix
    resource: "@SomeBundle/Resources/config/config.yml"

क्या किसी नियंत्रक या अन्य PHP कोड के बंडल के सापेक्ष फ़ाइल तक पहुंचने का कोई तरीका है? विशेष रूप से, मैं एक फ़ाइल को पार्स करने के लिए एक Symfony \ Component \ Yaml \ Parser ऑब्जेक्ट का उपयोग करने की कोशिश कर रहा हूं, और मैं उस फ़ाइल को बिल्कुल संदर्भित नहीं करना चाहता। अनिवार्य रूप से, मैं यह करना चाहता हूं:

$parser = new Parser();
$config = $parser->parse( file_get_contents("@SomeBundle/Resources/config/config.yml") );

मैंने Symfony \ Component \ Finder \ Finder वर्ग की जाँच की है, लेकिन मुझे नहीं लगता कि मैं वही देख रहा हूँ। कोई विचार? या शायद मैं ऐसा करने का एक बेहतर तरीका पूरी तरह से देख रहा हूँ?

जवाबों:


179

तथ्य की बात के रूप में, एक सेवा है जिसे आप इसके लिए उपयोग कर सकते हैं, कर्नेल ( $this->get('kernel'))। यह एक विधि कहा जाता है locateResource()

उदाहरण के लिए:

$kernel = $container->getService('kernel');
$path = $kernel->locateResource('@AdmeDemoBundle/path/to/file/Foo.txt');

5
ठीक वही जो मेरे द्वारा खोजा जा रहा था! $ this-> प्राप्त ( 'गिरी') -> locateResource ( "@ SomeBundle / संसाधन / config / config.yml"); // पूरी तरह से काम किया
थॉमस केली

9
@ tomtheman5: इसके अपवादों को पकड़ना सुनिश्चित करें। यह विधि फेंकता है \InvalidArgumentException, यदि फ़ाइल नहीं मिल सकती है या नाम मान्य नहीं है, और \RuntimeException, यदि नाम में अमान्य / असुरक्षित वर्ण हैं।
किडिल्डेन

2
आपको केवल +1 से अधिक देना पसंद करेंगे।
फ्लू

आप (यदि बिलकुल) इस पद्धति का प्रयोग एक सिद्धांत संस्था के अंदर करेंगे, जो (मुझे नहीं लगता) कर्नेल तक पहुँच होगी (या होनी चाहिए)?
माइकल। लेमली

1
@Morslamina ने फजीहत का जवाब दिया।
टेक

78

थॉमस केली का उत्तर अच्छा है (और काम करता है!) लेकिन अगर आप निर्भरता इंजेक्शन का उपयोग कर रहे हैं और / या अपने कोड को सीधे कर्नेल पर बाँधना नहीं चाहते हैं, तो आप फ़ाइललेकर क्लास / सेवा का उपयोग करना बेहतर समझते हैं:

$fileLocator = $container->get('file_locator');
$path = $fileLocator->locate('@MyBundle/path/to/file.txt')

$fileLocatorका एक उदाहरण होगा \Symfony\Component\HttpKernel\Config\FileLocator$pathफ़ाइल के लिए पूर्ण, पूर्ण पथ होगा।

भले ही file_locatorसेवा स्वयं कर्नेल का उपयोग करती है, यह एक बहुत छोटी निर्भरता है (अपने स्वयं के कार्यान्वयन के लिए स्थानापन्न करना, परीक्षण परीक्षण का उपयोग करना आसान है, आदि)

निर्भरता इंजेक्शन के साथ इसका उपयोग करने के लिए:

# services.yml

services:
    my_bundle.my_class:
        class: MyNamespace\MyClass
        arguments:
            - @file_locator

# MyClass.php

use Symfony\Component\Config\FileLocatorInterface as FileLocator;

class MyClass
{
    private $fileLocator;

    public function __construct(FileLocator $fileLocator)
    {
        $this->fileLocator = $fileLocator;
    }

    public function myMethod()
    {
        $path = $this->fileLocator->locate('@MyBundle/path/to/file.txt')
    }
}

अच्छी बात है, लेकिन FileLocator में कर्नेलइंटरफेस इंजेक्ट हो जाता है, इसलिए मूल रूप से, आप कुछ बेहतर नहीं करते हैं यदि आप कर्नेल के बजाय FileLocator को इंजेक्ट करते हैं :)
tomazahlin

10
मैं आपकी बात देख रहा हूं, और मैंने ऐसा सोचा। हालाँकि, समस्या यह नहीं है कि "क्या कोड लोड / निष्पादित किया गया है?", लेकिन "कोड किस MyClassपर निर्भर करता है?"। वर्तमान FileLocatorकार्यान्वयन का उपयोग करता है KernelInterface, लेकिन अगर भविष्य में यह परिवर्तन MyClassइसके बारे में जानने की जरूरत नहीं है। इसके अलावा, यह अब स्पष्ट हो गया है कि MyClassवास्तव में क्या जरूरत है (और इसे अन्य कर्नेल विशेषताओं के साथ कम करने के लिए प्रलोभन)। यह सब कहने के बाद, निर्माता को शायद Symfony\Component\Config\FileLocatorInterfaceइसके बजाय आवश्यकता होनी चाहिए Symfony\Component\HttpKernel\Config\FileLocator। फिर आप अपना खुद का लिख ​​सकते हैं।
आलसी

3
यह बेहतर उत्तर है
NDM

6

आप अपने एप्लिकेशन $container->getParameter('kernel.root_dir')का appफ़ोल्डर प्राप्त करने के लिए उपयोग कर सकते हैं , और अपनी निर्देशिकाओं को उस फ़ाइल में ब्राउज़ कर सकते हैं जिसे आप चाहते हैं।


बंडल किसी भी निर्देशिका में हो सकता है। सामान्य उदाहरण: src/Acme/Bundle/MyBundle, src/Acme/MyBundle, vendor/acme/my-bundle/srcऔर पर इतना।
Marius Balčytis

3

यदि आप ऐसा करना चाहते हैं, तो src/.../SomeBundle/...आप स्थित फ़ाइल __DIR__में वर्तमान फ़ाइल का पूर्ण पथ प्राप्त करने के लिए उपयोग कर सकते हैं । फिर Resources/...उस तरह से अपना रास्ता जोड़ें

$foo = __DIR__.'/Resources/config/config.yml';

@ruudy "केवल एक सशुल्क प्लान के साथ पंजीकृत उपयोगकर्ता ही नियम वर्णन के लिए पूर्ण पहुँच प्राप्त कर सकते हैं। यह पृष्ठ एक नमूना दिखाता है जिसे आप सदस्यता प्राप्त करके प्राप्त कर सकते हैं।"
प्रीफेल्ट

मैंने भुगतान नहीं किया और मैं इसका पूरा विवरण और इसे हल करने के तरीके की व्याख्या देख सकता हूं। शायद आपको केवल पंजीकरण करने की आवश्यकता है।
बरबादी

अब जब मैं पंजीकृत हो गया हूं तो मैं पेज देख सकता हूं। सबसे पहले यह कहता है कि "नहीं करना चाहिए" और "नहीं" होना चाहिए। दूसरी बात यह है कि यह केवल तभी महत्वपूर्ण है जब आप अपने कोड को जनता के लिए जारी करने की योजना बनाते हैं या बाद में संसाधन पथ को ओवरराइड करने की योजना बनाते हैं। मेरी बंद स्रोत परियोजनाओं में ऐसा नहीं होगा, इसलिए यह मेरे लिए उतना महत्वपूर्ण नहीं है। यह उस संदर्भ पर निर्भर करता है जहां आप इसका उपयोग करने जा रहे हैं, यदि यह बिंदु आपके लिए महत्वपूर्ण है। फिर भी संकेत के लिए धन्यवाद।
प्रीफेल्ट

यदि आप सिफारिशों का पालन करते हैं, तो आप मार्ग का मजाक उड़ा सकते हैं, या परीक्षण उद्देश्यों के साथ इसके साथ खेल सकते हैं। Im नहीं अंग्रेजी मूल, बेहतर है इस php स्थिरांक का उपयोग सकारात्मक के रूप में न करें, Symfony2 जैसे ढांचे पर बहुत कम है।
बरबादी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.