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 ...


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.


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ń.


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;

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
}

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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.