Solução de problemas “A declaração de uso com nome não composto ... não tem efeito”

95

Recebendo esse erro quando coloco use Blog;no topo.

Aviso: a instrução de uso com nome não composto 'Blog' não tem efeito em ...

Blog é o meu namespace no qual tenho 3 classes: Artigo, Lista e Categoria e algumas funções.

Se eu mudar minha declaração para use Blog\Article;, ela funciona ...

Não posso apenas especificar os namespaces que desejo usar? Eu preciso dar aulas?

E se eu tiver funções dentro desses namespaces? Quando eu os chamo fora do namespace, sou forçado a acrescentar \Blog\o nome de cada um ...

Thelolcat
fonte
não, não estou usando nenhuma estrutura
thelolcat
1
Aconteceu comigo quando declarei meu arquivo namespace depois use Blah; .
Derek Illchuk
Também pode significar apenas que 'Blog' já foi incluído e você está tentando usá-lo uma segunda vez. Isso é comum se você estiver usando uma estrutura que já a incluiu no topo da cadeia.
Rhu
@DerekIllchuk se apenas esta pudesse ser uma resposta que eu pudesse votar a favor. Me salvou de muita dor de cabeça.
Eu tento tanto, mas eu choro mais ainda

Respostas:

90

PHP usenão é igual ao C ++ using namespace; ele permite definir um alias , não "importar" um namespace e, portanto, omitir o qualificador de namespace por completo.

Então, você pode fazer:

use Blog\Article as BA;

... para encurtá-lo, mas você não pode se livrar dele totalmente.


Conseqüentemente, use Blogé inútil, mas acredito que você poderia escrever:

use \ReallyLongNSName as RLNN;

Observe que você deve usar um líder \aqui para forçar o analisador a saber que ReallyLongNSNameé totalmente qualificado. Isso não é verdade para Blog\Article, que obviamente já é uma cadeia de namespaces:

Observe que, para nomes de namespace ( nomes de namespace totalmente qualificados contendo separador de namespace, como Foo\Bar em oposição a nomes globais que não, comoFooBar ), a barra invertida inicial é desnecessária e não recomendada, pois os nomes de importação devem ser totalmente qualificados e não são processados relativo ao namespace atual.

Lightness Races in Orbit
fonte
22
Ah, isso é péssimo. Então a usecoisa é realmente inútil, pode muito bem ser um acrônimo para isso :)
thelolcat
1
@thelolcat: Tem seus usos ... mas não aquele que você deseja. :) Ele faz parecer que poderia ser uma limitação irritante.
Lightness Races in Orbit de
7
Essa resposta é correta apenas para arquivos sem namespace. 1) Em um arquivo com namespace, não há necessidade de usar um \ à esquerda na useinstrução, porque seus argumentos são sempre vistos como absolutos (ou seja, começando do namespace global). 2) use Blog;não é necessariamente inútil: por exemplo, a partir de um espaço de nomes de arquivo como Blog\Util\CLI, permitiria que você escrevesse em Blog\Entry::method()vez de \Blog\Entry::method(). Não que isso seja realmente necessário, mas tem um efeito. Para obter um exemplo desse uso, consulte a estrutura Nette.
Zilk
24

Uma vez que esta questão aparece como o primeiro resultado no Google para este erro, direi como o corrigi.

Basicamente, se você tem um framework, digamos como no Yii2, você estará acostumado a ter que declarar classes como:

use Yii;
use yii\db\WhatEver;

class AwesomeNewClass extends WhatEver
{
}

Você obterá esse erro Use Yiiporque esta classe não tem namespace.

Como essa classe não tem namespace, ela herda automaticamente a tabela de símbolos global e, portanto, não precisa de coisas como essa definição, apenas remova-a.

Sammaye
fonte
SIM! Isso fez todo o sentido! :)
Mārtiņš Briedis
1
Para mim, o problema era que eu estava tentando usar um símbolo do namespace global, por exemplo, use \Passwordmas o php não gosta quando você tenta fazer isso sem um alias, então até use \Password as Passwordfunciona bem.
Kzqai
Votos negados por sugerir o uso de OOD quando o moderador estava procurando uma resposta mais geral com relação ao uso de namespaces.
Josh Habdas
1
@JoshH do que você está falando? Eu nem mesmo recebo sua última resposta. Você passou de dizer que não é o que algum moderador estava procurando para dar o link de algum cara sobre
trollagem
1
@JoshH (A propósito, odeio quando as pessoas fazem referência a blogs opinativos como esse como material confiável para responder a uma pergunta)
Sammaye
6

A useinstrução em PHP é realmente apenas uma conveniência para transformar um namespace longo em algo que pode ser um pouco mais fácil de ler. Na verdade não inclui nenhum arquivo ou faz qualquer outra coisa que afete o seu desenvolvimento, além de proporcionar comodidade. Uma vez que, Blognão é um apelido como algo que você não está ganhando com a conveniência. Eu poderia imaginar que você poderia fazer algo como

use \Blog as B;

E isso pode até funcionar. ( Pode-se argumentar que você realmente perde a conveniência aqui ao obscurecer, mas não é sobre isso que a questão se trata ) Porque na verdade você está alterando o Blognamespace para outra coisa. Usar Blog\Articlefunciona porque, de acordo com a documentação:

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

Portanto, seu snippet seria equivalente a:

use Blog\Article as Article;
Charles Sprayberry
fonte
1
Nunca chame nada, a Bmenos que você esteja escrevendo um código que não pode ser mantido ou que deseje estritamente causar dores de cabeça a outras pessoas.
Josh Habdas
2

O erro "A instrução de uso ... não tem efeito ..." também aparece se você tentar usar uma característica antes de uma definição de classe.

use My_trait; // should not be here

class My_class{
// use My_trait; should be here instead
}
Dieter Donnert
fonte
2

se você não quiser usar a sintaxe 'as' como

use \Blog as B;

definir um namespace para o arquivo

namespace anyname;

use Blog
Samehanwar
fonte