122

Getting this error when I put use Blog; at the top.

Warning: The use statement with non-compound name 'Blog' has no effect in...

Blog is my namespace in which I have 3 classes: Article, List and Category and a few functions.

If I change my statememnt to use Blog\Article; then it works...

Can't I just specify the namespaces I want to use? Do I need to provide classes?

What if I have functions within that namespaces? When I call them outside of the namespace, I'm forced to prepend \Blog\ to each one's name...

thelolcat
  • 10,995
  • 21
  • 60
  • 102

6 Answers6

107

PHP's use isn't the same as C++'s using namespace; it allows you to define an alias, not to "import" a namespace and thus henceforth omit the namespace qualifier altogether.

So, you could do:

use Blog\Article as BA;

... to shorten it, but you cannot get rid of it entirely.


Consequently, use Blog is useless, but I believe you could write:

use \ReallyLongNSName as RLNN;

Note that you must use a leading \ here to force the parser into knowing that ReallyLongNSName is fully-qualified. This isn't true for Blog\Article, which is obviously already a chain of namespaces:

Note that for namespaced names (fully qualified namespace names containing namespace separator, such as Foo\Bar as opposed to global names that do not, such as FooBar), the leading backslash is unnecessary and not recommended, as import names must be fully qualified, and are not processed relative to the current namespace.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • 23
    Ah that sucks. So the `use` thing is actually useless, might as well be an acronym for that :) – thelolcat Feb 16 '12 at 18:49
  • 1
    @thelolcat: It has its uses... just not the one that you want. :) It _does_ seem like it could be an annoying limitation. – Lightness Races in Orbit Feb 16 '12 at 18:55
  • 8
    This answer is only correct for non-namespaced files. 1) In a namespaced file, there is no need to use a leading \ in the `use` statement, because its arguments are always seen as absolute (i.e., starting from the global namespace). 2) `use Blog;` is not necessarily useless: for example, from a file namespaced as `Blog\Util\CLI`, it would enable you to write `Blog\Entry::method()` instead of `\Blog\Entry::method()`. Not that this is really necessary, but it does have an effect. For an example of this usage, see the Nette framework. – Zilk Aug 25 '13 at 09:28
37

Since this question appears as the first result on Google for this error I will state how I fixed it.

Basically if you have a framework, say like Yii2 you will be used to having to do declare classes like:

use Yii;
use yii\db\WhatEver;

class AwesomeNewClass extends WhatEver
{
}

You will get this error on Use Yii since this class has no namespace.

Since this class has no namespace it automatically inherits the global symbol table and so does not need things like this defining, just remove it.

Sammaye
  • 43,242
  • 7
  • 104
  • 146
  • 1
    YES! This made all the sense! :) – Mārtiņš Briedis Sep 24 '15 at 17:25
  • 2
    For me, the problem was that I was trying to use a symbol from the global namespace, e.g. `use \Password` but php doesn't like it when you try to do that without an alias, so even `use \Password as Password` works just fine. – Kzqai Feb 02 '16 at 16:24
  • Downvoted for suggesting use of OOD when moderator was looking for a more general answer with regard to use of namespaces. – vhs May 23 '17 at 08:27
  • @JoshH I did explain that I posted this because this question is the first google result – Sammaye May 23 '17 at 09:05
  • Understood. And that makes sense. http://harmful.cat-v.org/software/OO_programming/ – vhs May 23 '17 at 11:24
  • 1
    @JoshH what are you on about? I don't even get your last reply. You have gone from saying it is not what some moderator was looking for to giving some guy's link about OOP trolling – Sammaye May 23 '17 at 15:53
  • 1
    @JoshH (BTW I hate it when people reference opinionated blogs like that as authoritative material for answering a question) – Sammaye May 23 '17 at 15:57
  • @Sammaye Sorry if I offended you in any way. I just started writing PHP and noticed it has had closures for about 9 years yet every resource I come across reeks of OOD. OP asked "Do I need to provide classes?", and the answer to that question in general is no. – vhs May 24 '17 at 07:50
9

The use statement in PHP is really just a convenience to alias a long namespace into something that may be a little easier to read. It doesn't actually include any files or do anything else, that effects your development, besides providing convenience. Since, Blog isn't aliased as anything you aren't gaining any of the convenience. I could imagine you could do something like

use \Blog as B;

And that may even work. (It could be argued you actually lose convenience here by obscuring but that's not what the question is about) Because you're actually aliasing the Blog namespace to something else. Using Blog\Article works because, according to the docs:

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

So your snippet would be equivalent to:

use Blog\Article as Article;
Charles Sprayberry
  • 7,741
  • 3
  • 41
  • 50
  • 1
    Please don't ever call anything `B` unless you're actively writing unmaintainable code or strictly desire to cause others headaches. – vhs May 23 '17 at 08:29
6

if you don't want to use 'as' syntax like

use \Blog as B;

define a namespace for the file

namespace anyname;

use Blog
samehanwar
  • 3,280
  • 2
  • 23
  • 26
2

The error "The use statement ... has no effect..." also pops up if you try to use a trait before a class definition.

use My_trait; // should not be here

class My_class{
// use My_trait; should be here instead
}
Dieter Donnert
  • 192
  • 2
  • 9
2

Perhaps it's something like

namespace Path\To\Your\Namespace\Blog;

use Blog; // Redundant

class Post {
    public $linkedArticle;

    public function __construct($article = null)
    {
        $this->linkedArticle = $article ?? new Blog\Article();
    }
}

Blog is already available, because that's the namespace you're in, so you can use new Blog\Article(); without use Blog; at the top. That's exactly what the error tells you - the added line has no effect.

Pointless:

use SingleNonNestedClassThatIsAlreadyPresentInTheCurrentNamespace;

Useful:

use SingleNonNestedClassThatIsAlreadyPresentInTheCurrentNamespace as Phew;

If you on the other hand wish to use new Article() then you can do it like this.

namespace Path\To\Your\Namespace\Blog;

use Blog\Article; // Equivalent to "use Blog\Article as Article;"

class Post {
    public $linkedArticle;

    public function __construct($article = null)
    {
        $this->linkedArticle = $article ?? new Article();
    }
}

In practice you'd do something like

// Fairly separated domains
use Some\TooLong\Namespace\App\User;
use Some\TooLong\Namespace\App\Ecommerce;
use Some\TooLong\Namespace\App\Auth;

but not necessarilly

// Two tools in same domain
use Some\TooLong\Namespace\App\Ecommerce\Cart;
use Some\TooLong\Namespace\App\Ecommerce\Checkout;

as well. I'm positive there are better examples than this ;)

s3c
  • 1,481
  • 19
  • 28