Page 1 of 3

Namespaces are here!

Posted: Fri Aug 17, 2007 8:06 am
by Chris Corbyn
I tend to check what's going on in snaps.php.net every month or so. Latest PHP6 development I see :)
README.namespaces wrote:Design
======

Main assumption of the model is that the problem that we are to solve is the
problem of the very long class names in PHP libraries. We would not attempt
to take autoloader's job or create packaging model - only make names
manageable.

Namespaces are defined the following way:

Zend/DB/Connection.php:

Code: Select all

<?php 
namespace Zend::DB;

class Connection {
}

function connect() {
}
?>
Namespace definition does the following:
All class and function names inside are automatically prefixed with
namespace name. Inside namespace, local name always takes precedence over
global name. It is possible to use the same namespace in several PHP files.
The namespace declaration statement must be the very first statement in
file.

Every class and function from namespace can be referred to by the full name
- e.g. Zend::DB::Connection or Zend::DB::connect - at any time.

Code: Select all

<?php
require 'Zend/Db/Connection.php';
$x = new Zend::DB::Connection;
Zend::DB::connect();
?>
Namespace or class name can be imported:

Code: Select all

<?php 
require 'Zend/Db/Connection.php';
import Zend::DB;
import Zend::DB::Connection as DbConnection;
$x = new Zend::DB::Connection();
$y = new DB::connection();
$z = new DbConnection();
DB::connect();
?>
I'm just compiling the source now so I can have a play around :)

Posted: Fri Aug 17, 2007 8:20 am
by superdezign
I like the idea, but it still doesn't seem any easier.

Posted: Fri Aug 17, 2007 8:27 am
by Chris Corbyn
It actually doesn't look great :(

Foo/Thing/Example.php

Code: Select all

<?php

namespace Foo::Thing;

class Example {
  public function __construct() {
    echo "Foo::Thing::Example instantiated...\n";
  }
}
Bar/Example.php

Code: Select all

<?php

namespace Bar;

class Example {
  public function __construct() {
    echo "Bar::Example instantiated...\n";
  }
}

Code: Select all

<?php

require_once "Foo/Thing/Example.php";
require_once "Bar/Example.php";

import Foo::Thing::Example;

$a = new Example();

import Bar::Example;

$b = new Example();

Code: Select all

d11wtq@pc-cac:~/php6-<span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span>$ /usr/local/php6/bin/php test.php 

Fatal error: Cannot reuse import name in /home/d11wtq/php6-<span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span>/test.php on line 10
d11wtq@pc-cac:~/php6-<span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span>$
I deliberately wanted to see if you could use the same class name in a different namespace more than once per-file. Once you import one class that's it for the entire file. You have to explicitly reference the locations of other classes. This works:

Code: Select all

<?php

require_once "Foo/Thing/Example.php";
require_once "Bar/Example.php";

import Foo::Thing::Example;

$a = new Example();

$b = new Bar::Example();

Posted: Fri Aug 17, 2007 8:30 am
by jason
Wow! So let me get this straight... instead of doing this:

Code: Select all

<?php
require_once "Cereal/Report/ReportCreator.php";
$RptCreator = new Cereal_Report_ReportCreator();
?>
I can do

Code: Select all

<?php
import Cereal::Report;
$RptCreator = new Report::ReportCreator();
?>
Yeah, I can see the major improvements here.

BuzzWord Approved!

Posted: Fri Aug 17, 2007 8:32 am
by jason
Oh, wait...

You have to require/include the files still, and then import the namespaces?

Posted: Fri Aug 17, 2007 8:35 am
by superdezign
Actually jason, it looks like you still have to include the file, which is why I don't think it's much easier. It doesn't look to shorten the code in any way, and d11 has shown that it doesn't differentiate between multiple namespaces in the same file. Maybe I'm missing the advantages.

Edit: It appears you've noticed, jason. :P Didn't see that post.

Posted: Fri Aug 17, 2007 8:35 am
by Chris Corbyn
jason wrote:Oh, wait...

You have to require/include the files still, and then import the namespaces?
Well, I'm guessing a call to "import" will invoke __autoload() behaviour. I have noticed they don't give any wanring if you do this though:

Code: Select all

import No::Such::Namespace; //I'd expect a warning please
Can't be too critical though, this did only appear in the past few weeks :P

Posted: Fri Aug 17, 2007 8:39 am
by superdezign
I guess it's still a matter of design namespaces in a PHP environment. It still seems to escape me that OOP is relatively new to PHP, and PHP is still in development.

Posted: Fri Aug 17, 2007 8:40 am
by Chris Corbyn
Confirmed, this works like Java imports. I'd like the ability to import "*" though.

Code: Select all

<?php

import Foo::Thing::Example;

function __autoload($class) {
  echo $class;
  $file = str_replace("::", "/", $class) . ".php";
  require_once $file;
}

$a = new Example();

$b = new Bar::Example();

Posted: Fri Aug 17, 2007 11:39 am
by RobertGonzalez
I suppose a little more work in this and it will get really good, eh?

// Don't mind the Canadian in me. I have been on an eh? streak for the last few days without really knowing why

Posted: Fri Aug 17, 2007 3:11 pm
by jason
d11wtq wrote:Confirmed, this works like Java imports. I'd like the ability to import "*" though.

Code: Select all

<?php

import Foo::Thing::Example;

function __autoload($class) {
  echo $class;
  $file = str_replace("::", "/", $class) . ".php";
  require_once $file;
}

$a = new Example();

$b = new Bar::Example();
And to think, I could do:

Code: Select all

<?php
require_once 'Example.php';
require_once 'Bar/Example.php';

$a = new Example();
$b = new Bar_Example();
?>
Sorry, I just don't see how namespaces are going to help PHP other than making it buzz word compliant. The difference between your implementation with name spaces and my implementation is that my implementation is, at least in my opinion, much easier to maintain.

Just my opinion though.

Posted: Fri Aug 17, 2007 3:21 pm
by superdezign
Everah wrote:// Don't mind the Canadian in me. I have been on an eh? streak for the last few days without really knowing why
Hehe, I've noticed. I have a friend who was getting <span style='color:red;text-decoration:blink' title='Alert a moderator!'>grilled spam</span> tips from a Canadian guy that said 'eh' a lot and he started saying it after every question. :P It's pretty noticeable to me.

Edit: Apparently, a taboo word here on DevNet.

Posted: Fri Aug 17, 2007 3:34 pm
by Christopher
jason wrote:Sorry, I just don't see how namespaces are going to help PHP other than making it buzz word compliant. The difference between your implementation with name spaces and my implementation is that my implementation is, at least in my opinion, much easier to maintain.

Just my opinion though.
I agree and have always said that those clamoring for namespaces really were not thinking about that they were actually asking for. I think more useful and interesting would be some real import functionality, or even some syntax like:

Code: Select all

$obj = new MyClass from 'my/path';
// or
include_class "whatever";
Even some packaging support would be interesting...

Posted: Fri Aug 17, 2007 3:45 pm
by jason
_autoload was really cool... I thought. But the reality is that it just makes everything obfuscated.

include 'file' or require 'file' is the winner in my book. It's clear, precise, and does what it does.

Granted, despite trying the various frameworks out there, I'm of the mind of following the No-Framework Framework put forth by Mr. Lerdorf.

Posted: Fri Aug 17, 2007 3:48 pm
by Chris Corbyn
jason wrote:Sorry, I just don't see how namespaces are going to help PHP other than making it buzz word compliant. The difference between your implementation with name spaces and my implementation is that my implementation is, at least in my opinion, much easier to maintain.

Just my opinion though.
No, I have to agree with you completely right now. Finding how this has been implemented has been a bit of a let down really. It's not proper namespacing/package handling, it's just changing prefixes on class names. I'll still be watching to see what comes of this though. PEAR naming pretty much amounts to the same set of conventions except you use "::" rather than "_", and the "import" keyword provides nothing more than a handy shortcut.