Rozwiązywanie problemów „Instrukcja użycia z nazwą niebędącą składnikiem… nie ma wpływu”

97

Otrzymuję ten błąd, gdy umieszczam use Blog;na górze.

Ostrzeżenie: instrukcja użycia z nazwą niezłożoną „Blog” nie ma wpływu na ...

Blog to moja przestrzeń nazw, w której mam 3 klasy: Artykuł, Lista i Kategoria oraz kilka funkcji.

Jeśli zmienię swój status na, use Blog\Article;to działa ...

Czy nie mogę po prostu określić przestrzeni nazw, których chcę używać? Czy muszę organizować zajęcia?

A jeśli mam funkcje w tych przestrzeniach nazw? Kiedy dzwonię do nich poza przestrzenią nazw, jestem zmuszony do dodawania \Blog\każdego imienia ...

thelolcat
źródło
nie, nie używam żadnego frameworka
thelolcat
1
Zdarzyło mi się, gdy zadeklarowałem plik namespace po use Blah; .
Derek Illchuk
Może to również oznaczać, że „Blog” został już uwzględniony i próbujesz użyć go po raz drugi. Jest to powszechne, jeśli używasz frameworka, który zawierał go już wyżej w łańcuchu.
Rhu
@DerekIllchuk, gdyby tylko to mogła być odpowiedź, którą mógłbym zagłosować. Uratował mi wiele bólu głowy.
Bardzo się staram, ale płaczę mocniej

Odpowiedzi:

90

PHP useto nie to samo co C ++ using namespace; pozwala na zdefiniowanie aliasu , a nie na "importowanie" przestrzeni nazw i tym samym całkowite pominięcie kwalifikatora przestrzeni nazw.

Więc możesz zrobić:

use Blog\Article as BA;

... aby go skrócić, ale nie można się go całkowicie pozbyć.


W konsekwencji use Blogjest bezużyteczna, ale myślę, że można by napisać:

use \ReallyLongNSName as RLNN;

Zauważ, że musisz użyć wiodącego \tutaj, aby zmusić parser do stwierdzenia, że ReallyLongNSNamejest w pełni kwalifikowany. To nie jest prawdą w przypadku Blog\Article, co oczywiście jest już łańcuchem przestrzeni nazw:

Zwróć uwagę, że w przypadku nazw w przestrzeni nazw (w pełni kwalifikowane nazwy przestrzeni nazw zawierające separator przestrzeni nazw, takie jak Foo\Bar w przeciwieństwie do nazw globalnych, które tego nie robią, na przykładFooBar ), początkowy ukośnik odwrotny jest niepotrzebny i niezalecany, ponieważ nazwy importu muszą być w pełni kwalifikowane i nie są przetwarzane względem bieżącej przestrzeni nazw.

Lekkość wyścigów na orbicie
źródło
22
Ach, to jest do bani. Więc userzecz jest właściwie bezużyteczna, równie dobrze może być akronimem na to :)
thelolcat
1
@thelolcat: Ma swoje zastosowania ... ale nie takie, które chcesz. :) Wygląda na to, że może to być denerwujące ograniczenie.
Wyścigi lekkości na orbicie
7
Ta odpowiedź jest poprawna tylko w przypadku plików bez przestrzeni nazw. 1) W pliku z przestrzenią nazw nie ma potrzeby używania usepoczątkowego znaku \ w instrukcji, ponieważ jego argumenty są zawsze postrzegane jako bezwzględne (tj. Począwszy od globalnej przestrzeni nazw). 2) use Blog;niekoniecznie jest bezużyteczne: na przykład z pliku o przestrzeni nazw as Blog\Util\CLI, umożliwiłoby to pisanie Blog\Entry::method()zamiast \Blog\Entry::method(). Nie żeby to było naprawdę konieczne, ale ma wpływ. Aby zapoznać się z przykładem tego użycia, zobacz platformę Nette.
Zilk,
24

Ponieważ to pytanie pojawia się jako pierwszy wynik tego błędu w Google, podam, jak go naprawiłem.

Zasadniczo, jeśli masz framework, powiedzmy jak Yii2, przyzwyczaisz się do deklarowania klas takich jak:

use Yii;
use yii\db\WhatEver;

class AwesomeNewClass extends WhatEver
{
}

Ten błąd zostanie wyświetlony, Use Yiiponieważ ta klasa nie ma przestrzeni nazw.

Ponieważ ta klasa nie ma przestrzeni nazw, automatycznie dziedziczy globalną tablicę symboli, a więc nie potrzebuje takich rzeczy, jak to definiowanie, po prostu ją usuń.

Sammaye
źródło
TAK! To miało sens! :)
Mārtiņš Briedis
1
Dla mnie problem polegał na tym, że próbowałem użyć symbolu z globalnej przestrzeni nazw, np. use \PasswordPhp nie lubi tego, gdy próbujesz to zrobić bez aliasu, więc nawet use \Password as Passworddziała dobrze.
Kzqai
Głos za sugestią użycia OOD, gdy moderator szukał bardziej ogólnej odpowiedzi w odniesieniu do korzystania z przestrzeni nazw.
Josh Habdas
1
@JoshH o czym ty mówisz? Nie dostaję nawet twojej ostatniej odpowiedzi. Przeszedłeś od stwierdzenia, że ​​to nie jest to, czego szukał moderator, do podania linku do jakiegoś faceta na temat trollingu OOP
Sammaye
1
@JoshH (Nawiasem mówiąc, nienawidzę, kiedy ludzie odnoszą się do upartych blogów, takich jak ten, jako autorytatywny materiał do odpowiedzi na pytanie)
Sammaye
6

useOświadczenie w PHP jest naprawdę tylko wygoda alias długa nazw w coś, co może być nieco łatwiejsze do odczytania. W rzeczywistości nie zawiera żadnych plików ani niczego innego, co wpływa na twój rozwój, poza wygodą. Ponieważ Blognie jest aliasowany jako coś, czego nie zyskujesz żadnej z wygody. Mogę sobie wyobrazić, że możesz zrobić coś takiego

use \Blog as B;

I to może nawet zadziałać. ( Można by argumentować, że w rzeczywistości tracisz wygodę przez zaciemnianie, ale nie o to chodzi ) Ponieważ tak naprawdę aliasujesz Blogprzestrzeń nazw na coś innego. Używanie Blog\Articledziała, ponieważ zgodnie z dokumentacją:

// this is the same as use My\Full\NSname as NSname
use My\Full\NSname;

Twój fragment byłby więc odpowiednikiem:

use Blog\Article as Article;
Charles Sprayberry
źródło
1
Nigdy nie dzwoń do niczego, Bchyba że aktywnie piszesz kod nie do utrzymania lub ściśle chcesz sprawiać innym ból głowy.
Josh Habdas
2

Jeśli spróbujesz użyć cechy przed definicją klasy, pojawi się również błąd „Instrukcja use ... nie ma wpływu ...”.

use My_trait; // should not be here

class My_class{
// use My_trait; should be here instead
}
Dieter Donnert
źródło
2

jeśli nie chcesz używać składni „as”, takiej jak

use \Blog as B;

zdefiniuj przestrzeń nazw dla pliku

namespace anyname;

use Blog
samehanwar
źródło