I've never seen this structure anywhere, so I wonder if there's something wrong with an expression like this:
if (condition) {
use Symfony\Component\HttpFoundation\Response;
}
The only thing use does is to alias a class name. That's it. Nothing more.
Instead of having to repeatedly write the fully qualified classname in your script:
$q = new \Foo\Bar\Baz\Quux;
if ($q instanceof \Foo\Bar\Baz\Quux) ...
You can shorten that to:
use Foo\Bar\Baz\Quux;
$q = new Quux;
if ($q instanceof Quux) ...
As such, it makes absolutely no sense to want to use use conditionally. It's just a syntactic helper; if it could be used conditionally your script syntax would become ambiguous, which is something nobody wants.
It doesn't reduce code loading, because code is only loaded explicitly by require/include calls or via autoloading. The latter one is greatly preferred, since it already lazily springs into action only when needed.
This will throw a syntax error. From TFM:
The use keyword must be declared in the outermost scope of a file
(the global scope) or inside namespace declarations. This is because
the importing is done at compile time and not runtime, so it cannot be
block scoped.
Related
I've never seen this structure anywhere, so I wonder if there's something wrong with an expression like this:
if (condition) {
use Symfony\Component\HttpFoundation\Response;
}
The only thing use does is to alias a class name. That's it. Nothing more.
Instead of having to repeatedly write the fully qualified classname in your script:
$q = new \Foo\Bar\Baz\Quux;
if ($q instanceof \Foo\Bar\Baz\Quux) ...
You can shorten that to:
use Foo\Bar\Baz\Quux;
$q = new Quux;
if ($q instanceof Quux) ...
As such, it makes absolutely no sense to want to use use conditionally. It's just a syntactic helper; if it could be used conditionally your script syntax would become ambiguous, which is something nobody wants.
It doesn't reduce code loading, because code is only loaded explicitly by require/include calls or via autoloading. The latter one is greatly preferred, since it already lazily springs into action only when needed.
This will throw a syntax error. From TFM:
The use keyword must be declared in the outermost scope of a file
(the global scope) or inside namespace declarations. This is because
the importing is done at compile time and not runtime, so it cannot be
block scoped.
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...
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.
http://php.net/manual/en/language.namespaces.importing.php
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.
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;
if you don't want to use 'as' syntax like
use \Blog as B;
define a namespace for the file
namespace anyname;
use Blog
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
}
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 ;)
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...
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.
http://php.net/manual/en/language.namespaces.importing.php
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.
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;
if you don't want to use 'as' syntax like
use \Blog as B;
define a namespace for the file
namespace anyname;
use Blog
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
}
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 ;)
Is there a way to make sure that the file exists before using the classes name in a file
This is to avoid errors incase it doesn't exist? I have researched this but nobody tells you how to do it. Maybe thats because there isn't a way or its only a way that secret php coders knew so please dont dislike this question because of the amount of information given about it.
I tried
if (class_exists("Authentication"))
{
use go\Authentication;
}
But I get this error
Parse error: syntax error, unexpected 'use' (T_USE) in C:\xampp\htdocs\index.php on line 29
I also tried this method
if (file_exists("/go/authentication.php") { use go\Authentication; }
And it gave me the same error as the previouse method
Besides of your original intention, in the documentation you can read:
The use keyword must be declared in the outermost scope of a file (the global scope) or inside namespace declarations. This is because the importing is done at compile time and not runtime, so it cannot be block scoped. The following example will show an illegal use of the use keyword:
Which means that it should be used in the top of the file or, at least, in the outermost scope. While your case might be the outermost scope, it is bound to a conditional, which makes your rule illegal, similarly to the example provided in the documentation:
<?php
namespace Languages;
class Greenlandic
{
use Languages\Danish;
...
}
?>
About your problem, you could simply do:
if (class_exists("Authentication"))
$Auth = new Authentication();
However, have a look into autoloading, since that seems more likely what you are looking for.
You are using use wrong!!
The 'use' keyword must be declared in the outermost scope of a file
(the global scope) or inside namespace declarations. This is because
the importing is done at compile time and not runtime, so it cannot be
block
scoped.
As far as loading the class on the fly is concerned. You can use autoloading as suggested in the comments
On a side note. If your class is found inside a namespace such as
namespace foo\bar;
class tar{
}
then the right way to check it exists is not
class_exists('tar')
but rather:
class_exists('\foo\bar\tar')
or
use foo\bar;
class_exists('tar');
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...
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.
http://php.net/manual/en/language.namespaces.importing.php
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.
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;
if you don't want to use 'as' syntax like
use \Blog as B;
define a namespace for the file
namespace anyname;
use Blog
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
}
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 ;)