Bagaimana cara mendapatkan direktori root dari aplikasi Symfony2?

121

Apa cara terbaik untuk mendapatkan direktori aplikasi root dari dalam pengontrol? Apakah mungkin untuk mendapatkannya di luar pengontrol?

Sekarang saya mendapatkannya dengan meneruskannya (dari parameter) ke layanan sebagai argumen, seperti ini:

services:

    sr_processor:
        class: Pro\Processor
        arguments: [%kernel.root_dir%]

Apakah ada cara yang lebih baik dan lebih sederhana untuk mendapatkan informasi ini di Symfony2?

Dawid Ohia
sumber
13
solusi Anda adalah yang terbaik
Inoryy
4
Anda mencampurkan layanan dan pengontrol yo
john Smith
4
Sekali lagi untuk Symfony 3.3 dan seterusnya gunakan %kernel.project_dir%untuk mendapatkan root dari proyek Anda.
Muzafar Ali
1
pastikan untuk merangkum literal dalam tanda kutip: ["%kernel.root_dir%"]
ochitos

Jawaban:

220

UPDATE 2018-10-21:

Pada minggu ini, getRootDir()sudah tidak digunakan lagi. Silakan gunakan getProjectDir()sebagai gantinya, seperti yang disarankan di bagian komentar oleh Muzaraf Ali.

—-

Gunakan ini:

$this->get('kernel')->getRootDir();

Dan jika Anda menginginkan root web :

$this->get('kernel')->getRootDir() . '/../web' . $this->getRequest()->getBasePath();

ini akan bekerja dari metode aksi pengontrol ...

EDIT: Untuk layanan, saya pikir cara Anda melakukannya sebersih mungkin, meskipun saya akan memberikan layanan kernel lengkap sebagai argumen ... tetapi ini juga akan melakukan trik ...

Jovan Perovic
sumber
3
+1 tetapi tidak akurat untuk symfony2. Gunakan sebagai gantinya:$this->get('kernel')->getRootDir() . '/../..' . $this->getRequest()->getBasePath();
Sebastian
36
Solusi ini hanya tepat untuk pengontrol. Di sini masalahnya adalah tentang layanan. Ngomong-ngomong, mengapa melewatkan seluruh container hanya untuk mendapatkan variabel? Jauh lebih baik untuk meneruskan% kernel.root_dir%
Massimiliano Arione
2
Massimiliano benar, dan sebagai tambahan, saya menggunakan $this->container->getParameter('kernel.cache_dir')pengontrol alih-alih solusi yang Anda berikan
kekuranganovic10
2
Ini lebih pada topik layanan Anda yang telah containerdisuntikkan :) Jika Anda mengikuti praktik terbaik, menyuntikkan containerharus dihindari dengan segala cara. Adapun solusi untuk mendapatkan webdirektori, saya masih menggunakan yang saya berikan di atas;)
Jovan Perovic
4
Pada Symfony 3.3 dan seterusnya gunakan %kernel.project_dir%/web/sebagai pengganti%kernel.root_dir%/../web/
Muzafar Ali
15

Di Symfony 3.3 Anda dapat menggunakan

$projectRoot = $this->get('kernel')->getProjectDir();

untuk mendapatkan root web / proyek.

Chris
sumber
8

Jika Anda menggunakan jalur ini untuk mengakses bagian proyek yang bukan merupakan kode (misalnya direktori unggahan, atau database SQLite), mungkin lebih baik mengubah jalur menjadi parameter, seperti ini:

parameters:
    database_path: '%kernel.root_dir%/../var/sqlite3.db'

Parameter ini dapat disuntikkan di mana pun Anda membutuhkannya, jadi Anda tidak perlu lagi mengotak-atik jalur dalam kode Anda. Selain itu, parameter dapat diganti pada waktu penerapan. Akhirnya, setiap programmer yang memelihara akan memiliki ide yang lebih baik untuk apa Anda menggunakannya.

Pembaruan: Memperbaiki penggunaan konstan kernel.root_dir.

MauganRa
sumber
6

Anda juga dapat menggunakan ekspresi reguler selain ini:

    $directoryPath = $this->container->getParameter('kernel.root_dir') . '/../web/bundles/yourbundle/';
    $directoryPath = preg_replace("/app..../i", "", $directoryPath);
    echo $directoryPath;
Tragaknight
sumber
2

Sejak Symfony 3.3 Anda dapat menggunakan pengikatan, seperti

services:
_defaults:
    autowire: true      
    autoconfigure: true
    bind:
        $kernelProjectDir: '%kernel.project_dir%'

Setelah itu Anda dapat menggunakan parameter $ kernelProjectDir di kontroler ATAU layanan apa pun. Seperti

class SomeControllerOrService
{
    public function someAction(...., $kernelProjectDir)
    {
          .....
Andrew Zhilin
sumber