# forbid use declaration outside of a namespace in PHP 7

- Thread: https://externals.io/message/78446
- Original archive: https://news-web.php.net/php.internals/78446
- Started by Robert Stoll on 2014-10-29T19:54:56+00:00
- Messages: 15
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #78446 — Robert Stoll — 2014-10-29T19:54:56+00:00

URL: https://externals.io/message/78446#78446

Heya, 

I always found it very ugly that it is possible to define a use outside of a namespace. Consider the following:

namespace{ //default namespace
}

use foo\Bar;

namespace test{
  new Bar(); //error, test\Bar not found
}

After some thoughts it is quite clear that Bar is test\Bar and not foo\Bar inside of the namespace test. But consider
the following example which is not so obvious:

use foo\Bar;
namespace test;
new Bar(); //error, test\Bar not found

The use declaration looks like a normal use declaration at first glance. 
I do not see why we should actually support this "feature" any longer and thus suggest to remove it in PHP 7. Although,
it is not a bug (the use declaration is simply ignored as far as I can tell) I suppose it confuses the user.
Nevertheless, even if we declare it as a "feature" I think it should at least not be a "feature" of the specification of
PHP 7.

Thoughts?

Cheers,
Robert


ps: I first started the discussion @standards, just if you should wonder why it pops up here now as well:
http://news.php.net/php.standards/528

---

## #78869 — Robert Stoll — 2014-11-11T12:11:27+00:00

URL: https://externals.io/message/78446#78869 · In reply to: #78446

> -----Ursprüngliche Nachricht-----
> Von: Robert Stoll [mailto:php@tutteli.ch]
> Gesendet: Mittwoch, 29. Oktober 2014 20:55
> An: 'PHP Internals'
> Betreff: [PHP-DEV] forbid use declaration outside of a namespace in PHP 7
> 
> Heya,
> 
> I always found it very ugly that it is possible to define a use outside of a namespace. Consider the following:
> 
> namespace{ //default namespace
> }
> 
> use foo\Bar;
> 
> namespace test{
>   new Bar(); //error, test\Bar not found }
> 
> After some thoughts it is quite clear that Bar is test\Bar and not foo\Bar inside of the namespace test. But consider
the
> following example which is not so obvious:
> 
> use foo\Bar;
> namespace test;
> new Bar(); //error, test\Bar not found
> 
> The use declaration looks like a normal use declaration at first glance.
> I do not see why we should actually support this "feature" any longer and thus suggest to remove it in PHP 7.
Although, it is
> not a bug (the use declaration is simply ignored as far as I can tell) I suppose it confuses the user.
> Nevertheless, even if we declare it as a "feature" I think it should at least not be a "feature" of the specification
of PHP 7.
> 
> Thoughts?
> 
> Cheers,
> Robert
> 
> 
> ps: I first started the discussion @standards, just if you should wonder why it pops up here now as well:
> http://news.php.net/php.standards/528
> 
> 
> 
> --
>  

No one else who thinks this "feature" should be removed in PHP 7 ?

---

## #78870 — Chris Wright — 2014-11-11T12:38:47+00:00

URL: https://externals.io/message/78446#78870 · In reply to: #78869

> > […]
> of a namespace. Consider the following:
> > […]
> foo\Bar inside of the namespace test. But consider
> the
> > […]
> and thus suggest to remove it in PHP 7.
> Although, it is
> > […]
> suppose it confuses the user.
> > […]
> least not be a "feature" of the specification
> of PHP 7.
> > […]
> why it pops up here now as well:
> > […]
> visit: http://www.php.net/unsub.php
>
> No one else who thinks this "feature" should be removed in PHP 7 ?
>
>
I would say that the lack of anyone saying "no, don't do this" probably
means everyone is OK with it. Suggest you work up a patch and PR it, then
ping the list to highlight it for further discussion.

---

## #78871 — Robert Stoll — 2014-11-11T13:20:21+00:00

URL: https://externals.io/message/78446#78871 · In reply to: #78870

> I would say that the lack of anyone saying "no, don't do this" probably means everyone is OK with it. Suggest you work up a
> patch and PR it, then ping the list to highlight it for further discussion.
> 

Sounds reasonable but unfortunately I do not have time at the moment to work up a patch and when I have time (in half a year or so) it might be too late for PHP 7 and the change would need to wait for PHP 8 since it is not backward compatible. That is the reason why I hope we could agree on the topic, remove the corresponding sentence from the spec and I could patch up a fix when I have time for it.

---

## #78872 — Andrea Faulds — 2014-11-11T13:29:11+00:00

URL: https://externals.io/message/78446#78872 · In reply to: #78871

> 
> 
> > […]
> 
> Sounds reasonable but unfortunately I do not have time at the moment to work up a patch and when I have time (in half a year or so) it might be too late for PHP 7 and the change would need to wait for PHP 8 since it is not backward compatible. That is the reason why I hope we could agree on the topic, remove the corresponding sentence from the spec and I could patch up a fix when I have time for it.

I don’t like the sound of changing the spec before the implementation.
--
Andrea Faulds
http://ajf.me/

---

## #78874 — Stas Malyshev — 2014-11-11T23:45:24+00:00

URL: https://externals.io/message/78446#78874 · In reply to: #78872

Hi!

> I don’t like the sound of changing the spec before the implementation.

I agree - whatever are our considerations and limitations on what we can
and can not do in PHP 7, the spec should reflect what is there.
Otherwise we end up releasing an implementation that does not match our
own spec, that'd be embarrassing.

-- 
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/

---

## #78878 — Robert Stoll — 2014-11-12T08:17:55+00:00

URL: https://externals.io/message/78446#78878 · In reply to: #78874

> -----Ursprüngliche Nachricht-----
> Von: Stas Malyshev [mailto:smalyshev@sugarcrm.com]
> Gesendet: Mittwoch, 12. November 2014 00:45
> An: Andrea Faulds; Robert Stoll
> Cc: Chris Wright; PHP Internals
> Betreff: Re: [PHP-DEV] forbid use declaration outside of a namespace in PHP 7
> 
> Hi!
> 
> > […]
> 
> I agree - whatever are our considerations and limitations on what we can and can not do in PHP 7, the spec should reflect
> what is there.
> Otherwise we end up releasing an implementation that does not match our own spec, that'd be embarrassing.
> 
Alright, fair enough. I will ping this list once a patch is ready.

---

## #78888 — Adam Harvey — 2014-11-12T20:45:08+00:00

URL: https://externals.io/message/78446#78888 · In reply to: #78869

> > […]
> the
> > […]
> Although, it is
> > […]
> of PHP 7.

Sorry, I apparently missed this the first time. Would this mean that
this sort of script (where we're using use statements without a
namespace) would no longer work?

<?php
use GuzzleHttp\Client;

include __DIR__.'/vendor/autoload.php';

$client = new Client;
// $client is a GuzzleHttp\Client object
?>

Because that strikes me as an irritating and unnecessary BC break for
people who are writing throwaway scripts (with no need to live in
namespaces) that pull in namespaced libraries to me.

Adam

---

## #78889 — Robert Stoll — 2014-11-12T21:27:29+00:00

URL: https://externals.io/message/78446#78889 · In reply to: #78888

> Sorry, I apparently missed this the first time. Would this mean that this sort of script (where we're using use statements
> without a
> namespace) would no longer work?
> 
> <?php
> use GuzzleHttp\Client;
> 
> include __DIR__.'/vendor/autoload.php';
> 
> $client = new Client;
> // $client is a GuzzleHttp\Client object ?>
> 
> Because that strikes me as an irritating and unnecessary BC break for people who are writing throwaway scripts (with no
> need to live in
> namespaces) that pull in namespaced libraries to me.
> 
> Adam
> 

That's still perfectly fine because in your code the use statement is not outside of a namespace, it is implicitly in the default namespace.
I am talking about the two following scenarios:

use \Exception;
namespace test;

$e = new Exception(); //would fails because test\Exception is unknown -> use was defined outside the namespace


Or
namespace a{
}

use some\UseDeclaration\which\is\outside\of\AnyNamespace as Useless;  // sorry for begin biased ^^

namespace test{
}


Cheers,
Robert

---

## #78890 — Rowan Collins — 2014-11-13T10:57:24+00:00

URL: https://externals.io/message/78446#78890 · In reply to: #78889

Robert Stoll wrote on 12/11/2014 21:27:

> That's still perfectly fine because in your code the use statement is not outside of a namespace, it is implicitly in the default namespace.

Surely if that's true of Adam's example, it's true of yours as well?

> namespace a{
> }
>
> use some\UseDeclaration\which\is\outside\of\AnyNamespace as Useless;  // sorry for begin biased ^^
>
> namespace test{
> }

This scenario looks identical to Adam's to me, unless you propose to 
look at the entirety of the file to detect if there is something other 
than a use statement in the default namespace.

For that matter, what about this:

use GuzzleHttp\Client;

include __DIR__.'/vendor/autoload.php';

$client = new Client;
// $client is a GuzzleHttp\Client object

namespace Foo;
$client = new Client;
// $client is a Foo\Client object

Certainly this code is not *sensible*, but it does have a meaningful 
behaviour, which derives directly from the previous examples and 
documented uses of the namespace keyword. I'm not sure how you'd 
distinguish between the various combinations here.

Regards,
-- 
Rowan Collins
[IMSoP]

---

## #78891 — johannes@schlueters.de — 2014-11-13T11:29:07+00:00

URL: https://externals.io/message/78446#78891 · In reply to: #78889

> That's still perfectly fine because in your code the use statement is not outside of a namespace, it is implicitly in the default namespace.
> I am talking about the two following scenarios:
> 
> use \Exception;
> namespace test;
> 
> $e = new Exception(); //would fails because test\Exception is unknown -> use was defined outside the namespace
> 
> 
> Or
> namespace a{
> }
> 
> use some\UseDeclaration\which\is\outside\of\AnyNamespace as Useless;  // sorry for begin biased ^^
> 
> namespace test{
> }

If I get it rigth this might break code by people who, for whatever
reason, combine multiple PHP files into a single one. (cat *.php >
full.php && php full.php)

johannes

---

## #78892 — Chris Wright — 2014-11-13T12:13:03+00:00

URL: https://externals.io/message/78446#78892 · In reply to: #78891

> 
>
> > […]
> not outside of a namespace, it is implicitly in the default namespace.
> > […]
> use was defined outside the namespace
> > […]
> sorry for begin biased ^^
> > […]
>
> If I get it rigth this might break code by people who, for whatever
> reason, combine multiple PHP files into a single one. (cat *.php >
> full.php && php full.php)
>
>
This would only break if the individual files were already invalid. Files
with namespace Name; style ns declarations couldn't be joined together in
this way anyway, and files using namespace Name { ... } style declarations
with use imports outside the block would be invalid on their own,
concatenating them wouldn't break (or fix) this situation. Unless I missed
something?

I must say actually that while I think a use declaration outside a
block-style namespace should be invalid, I'm about 50/50 on whether
something like this should be invalid:

<?php

use \Foo;
namespace Bar;

The current behaviour is certainly wrong, but in this case it might be good
to treat it as if the use declaration was after the ns declaration, rather
than making it invalid (I haven't looked at how easy this would be to
accomplish, though).


johannes

---

## #78893 — Robert Stoll — 2014-11-13T12:30:49+00:00

URL: https://externals.io/message/78446#78893 · In reply to: #78890

> -----Ursprüngliche Nachricht-----
> Von: Rowan Collins [mailto:rowan.collins@gmail.com]
> Gesendet: Donnerstag, 13. November 2014 11:57
> An: internals@lists.php.net
> Betreff: Re: AW: [PHP-DEV] forbid use declaration outside of a namespace in PHP 7
> 
> Robert Stoll wrote on 12/11/2014 21:27:
> 
> > […]
> default namespace.
> 
> Surely if that's true of Adam's example, it's true of yours as well?

[Robert Stoll] 
The difference is that I have specified a namespace and thus code outside of that namespace is no longer implicitly in the default namespace.

> > […]
> 
> This scenario looks identical to Adam's to me, unless you propose to look at the entirety of the file to detect if there is
> something other than a use statement in the default namespace.

[Robert Stoll] 
Same applies here, my use statement is outside of a namespace Adam's isn't.

> For that matter, what about this:
> 
> use GuzzleHttp\Client;
> 
> include __DIR__.'/vendor/autoload.php';
> 
> $client = new Client;
> // $client is a GuzzleHttp\Client object
> 
> namespace Foo;
> $client = new Client;
> // $client is a Foo\Client object
> 
> Certainly this code is not *sensible*, but it does have a meaningful behaviour, which derives directly from the previous
> examples and documented uses of the namespace keyword. I'm not sure how you'd distinguish between the various
> combinations here.
> 
> Regards,
> --
> Rowan Collins
> [IMSoP]
> 

[Robert Stoll]
I haven't tested it I am pretty sure this script would fail since $client = new Client is outside of a namespace - an error message something like "namespace must be the first statement" would show up.
If I rewrite your code to the following:

namespace{
  use GuzzleHttp\Client;
 
  include __DIR__.'/vendor/autoload.php';
 
  $client = new Client;
  // $client is a GuzzleHttp\Client object
  
namespace Foo{
  $client = new Client;
  // $client is a Foo\Client object
}

Then it would make sense (use statement is inside a namespace).

---

## #78894 — Robert Stoll — 2014-11-13T12:40:08+00:00

URL: https://externals.io/message/78446#78894 · In reply to: #78892

> -----Ursprüngliche Nachricht-----
> Von: are.you.winning@gmail.com [mailto:are.you.winning@gmail.com] Im Auftrag von Chris Wright
> Gesendet: Donnerstag, 13. November 2014 13:13
> An: Johannes Schlüter
> Cc: Robert Stoll; Adam Harvey; PHP Internals
> Betreff: Re: AW: [PHP-DEV] forbid use declaration outside of a namespace in PHP 7
> 
> 
> 
> > […]
> This would only break if the individual files were already invalid. Files with namespace Name; style ns declarations couldn't
> be joined together in this way anyway, and files using namespace Name { ... } style declarations with use imports outside
> the block would be invalid on their own, concatenating them wouldn't break (or fix) this situation. Unless I missed
> something?

[Robert Stoll] 
I share Chris' statement. Combining multiple files would only work if they all use namespace blocks or if they do not use any namespaces at all (and thus are implicitly in the default namespace).

> 
> I must say actually that while I think a use declaration outside a block-style namespace should be invalid, I'm about 50/50 on
> whether something like this should be invalid:
> 
> <?php
> 
> use \Foo;
> namespace Bar;
> 
> The current behaviour is certainly wrong, but in this case it might be good to treat it as if the use declaration was after the
> ns declaration, rather than making it invalid (I haven't looked at how easy this would be to accomplish, though).
> 

[Robert Stoll] 
I think it would be wrong to start to do such auto-fixes. Syntax which is wrong should emit a fatal error IMO (assuming we would disallow use-statement outside of a namespace). In this case the user has to move the statement down a few lines and it works again. Better than auto-fixing which might introduce unintended bugs.

> 
> johannes
> > […]

---

## #78895 — Rowan Collins — 2014-11-13T12:56:17+00:00

URL: https://externals.io/message/78446#78895 · In reply to: #78893

Robert Stoll wrote on 13/11/2014 12:30:
> > […]
> [Robert Stoll]
> The difference is that I have specified a namespace and thus code outside of that namespace is no longer implicitly in the default namespace.
>

Ah, OK, on further experimenting, and closer reading of the 
documentation, I see that you are right.

For anyone else wondering, the key quotes from the manual are:
- "A file containing a namespace must declare the namespace at the top 
of the file before any other code - with one exception: the declare 
<http://php.net/manual/en/control-structures.declare.php> keyword."
- "No PHP code may exist outside of the namespace brackets except for an 
opening declare statement."

So as soon as the keyword "namespace" appears somewhere in the file, 
there is no longer any implicit global non-namespaced code.

As such, it seems to me that allowing a "use" statement is simply a bug 
- no other code is allowed in that position, and the only documented 
exception to that rule is declare().

Regards,
-- 
Rowan Collins
[IMSoP]
