2015-12-17 14 views
9

Używam SensioLabs Insight do kontrolowania jakości mojego kodu.Dlaczego bezwzględne stałe ścieżki __DIR__ i __FILE__ nie powinny być używane w Symfony

Dla prostego przesłanie pliku, muszę uzyskać bezwzględną ścieżkę do mojego katalogu uploads:

protected function getUploadRootDir() 
{ 
    // the absolute directory path where uploaded 
    return __DIR__.'/../../../../web/'.$this->getUploadDir(); 
} 

Kod pochodzących bezpośrednio z oficjalnej dokumentacji (How to handle file uploads with Doctrine)

Ale SLInsight zgłosi ostrzeżenie, jeśli kod analizowane zawiera __DIR__ lub __FILE__ PHP magiczne stałe:

__DIR__ i __FILE__ stałe mogą powodować konflikt z systemem przesłonięcia zasobów Symfony.

W jaki sposób użycie tych stałych może powodować konflikty z Symfony?

Jak mogę ich uniknąć w moim kodzie?

+1

Tytuł wprowadza w błąd. Zaleca się ** stosowanie ** bezwzględnych stałych ścieżek '__FILE__' i' __DIR__' w ogóle. Lepiej używać lokalizatora plików Symfony zamiast * tylko wtedy, gdy używasz Symfony (lub lokalizatora plików) * w swoim projekcie. – axiac

+0

Dobra, zaktualizowałem to. Dziękuję – chalasr

+0

Szczerze mówiąc, gdybym zobaczył ten kod, moja reakcja byłaby "musi być lepsza droga niż to". Twarde kodowanie oznacza, że ​​żądana ścieżka ma dokładnie 4 poziomy, a następnie dir o nazwie "web", a następnie segment dynamiczny. To wygląda bardzo kruche i nieelastyczne. Na pewno cała ta ścieżka powinna być skonfigurowana gdzieś w stosunku do konkretnej bazy. – IMSoP

Odpowiedz

11

W przypadku klasy przesyłania plików możesz prawdopodobnie zignorować ten komunikat o błędzie. Ale w innych przypadkach lepiej użyć lokalizatora plików Symfony zamiast ścieżek plików hardcoding. Na przykład:

$path = $this->get('kernel')->locateResource('@AppBundle/Resources/config/services.xml'); 

Zamiast:

$path = __DIR__.'/../../../src/Acme/AppBundle/Resources/config/services.xml' 
+0

Cześć Mr Eguiluz, Czy to jest właściwe, aby użyć tego kodu w modelu jednostki? (* Kiedyś myślałem, że wywoływanie jądra lub innej usługi nie było "bardzo czyste" wewnątrz modelu ... *) – pbenard

+3

Cóż, powiedziałbym, że pobranie katalogu z obiektu nie jest już czyste. podmiot nie powinien być odpowiedzialny za to, aby wiedzieć, gdzie są przechowywane przesłane pliki (które mogą nie być nawet lokalnie, ale na przykład na S3). –

+0

Dzięki za wyjaśnienie Pan, i super ** ThankYou ** za całą pracę. – pbenard

7

To jest właściwie coś, co SensioLabs Insight nie obsługuje poprawnie. Ostrzega przed używaniem stałych ze względu na system nadpisywania zasobów, ale w wielu przypadkach te stałe są używane w miejscach, które nie są powiązane z systemem nadpisywania zasobów (co prawdopodobnie ma miejsce w przypadku tego kodu). Możesz więc zignorować ostrzeżenie w tym przypadku:

+0

Dziś rano Ostrzeżenie zostało podniesione na test jednostkowy. Ta reguła powinna być ograniczona do klas, które mogą używać systemu przesłonięcia zasobów symfony. http://prnt.sc/aa68cw – chalasr

0

Jeśli tworzysz pakiet innej firmy i chcesz, aby zlokalizować kilka zasobów, (dobrze) rozwiązanie proponowane przez @Javier nie ma zastosowania w tym wyjątek to

ServiceNotFoundException in ContainerBuilder.php line 816: 
You have requested a non-existent service "kernel". 

W tym przypadku rozwiązaniem jest użycie $this->getPath(), metodę dziedziczona przez BundleNameBundle z Symfony\Component\HttpKernel\Bundle\Bundle c dziewczyna.

Powoduje to ten sam wynik co realpath(__DIR__).

Wykonanie $this->getPath() . '/Resources/config/doctrine/mappings' jest takie samo jak realpath(__DIR__ . '/Resources/config/doctrine/mappings').

Pierwotnie zaproponowano here.

+0

Usługa 'kernel' nie jest dostępna w czasie kompilacji (najpierw dlatego, że jest syntetyczna), więc nie możesz jej użyć z przepustki kompilatora, ale działa ona dobrze z dowolnego środowiska wykonawczego. Tutaj kontekst jest jednostką, więc nie powinniśmy używać usługi, a ponieważ moja encja nie jest instancją pakietu (ponieważ nie ma to sensu), 'getPath' nie jest dostępna. Więc ignorowanie ostrzeżenia, o którym mowa w dwóch poprzednich odpowiedziach, pozostaje najlepszym rozwiązaniem, chyba – chalasr

+0

Tak, wiem. Dodałem odpowiedź, ponieważ to pytanie jest wyświetlane podczas wyszukiwania problemu w kontekście tworzenia pakietu. Ale proponowane tutaj rozwiązania nie są odpowiednie. Więc dodałem odpowiedź, więc kto i tak szuka rozwiązania w kontekście tworzenia pakietu, może to i tak znaleźć. Do wewnętrznego linkowania ... – Aerendir

Powiązane problemy