随着PHP5.3的出现,我当然期待使用名称空间。老实说,谁想写下面这行?
$viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
当越简洁:
$viewRenderer = HelperBroker::getStaticHelper('viewRenderer');
可以用吗?(假设您已经在较早的某个地方执行了'useZend::Controller::Action;'
……)
然而,虽然命名空间有望带来更具可读性的代码,尤其是库和框架中的代码,但PHP开发人员最终需要开始考虑抽象类和接口的合理标准。
例如,我们一直在ZendFramework中做如下事情:
Zend_Controller_Request_Abstract
Zend_View_Interface
这些约定使得使用find
或grep
查找抽象类和接口变得非常容易,而且可预测且易于理解。但是,它们不会很好地发挥作用与命名空间。为什么?请考虑以下事项:
namespace Zend::Controller::Request class Http extends Abstract { // ... }
发现问题了吗?Abstract
是PHP中的保留字。接口也是如此。考虑这个特别聚集的例子:
namespace Zend::View abstract class Abstract implements Interface { // ... }
我们在那里有两个保留字:Abstract
和Interface
。
几周前Stas、Dmitry和我坐下来讨论了这个问题,提出了迁移到PHP5.3的计划。在其他OOP语言中,例如Python、C#,接口是通过在接口前加上大写的“I”来表示的;在上面的例子中,我们会有Zend::View::IView
。我们认为这将是一个明智的步骤,因为它会将接口保留在命名空间内,并在视觉上表示它。我们还决定这个约定对抽象类有意义:Zend::View::AView
。所以,我们的两个例子变成了:
namespace Zend::Controller::Request class Http extends ARequest { // ... }
和:
namespace Zend::View abstract class AView implements IView { // ... }
另一件看起来可能会影响OOP库和框架的事情是自动加载,特别是在使用异常时。例如,考虑一下:
namespace Foo::Bar class Baz { public function status() { throw new Exception("This isn't what you think it is"); } }
您希望异常属于Foo::Bar::Exception
类,对吗?错误;这将是一个标准的Exception
。要解决此问题,您可以执行以下操作:
namespace Foo::Bar class Baz { public function status() { throw new namespace::Exception("This is exactly what you think it is"); } }
通过使用namespace
关键字,您告诉PHP引擎显式使用当前命名空间中的Exception类。我还发现这在语义上更正确——它更明确地表明您正在抛出特定类型的异常,并且可以在以后轻松找到并用备用声明替换它们。
我想推荐其他图书馆采用类似的标准——它们是明智的,并且已经符合PEAR/Horde/ZF编码标准。你怎么说?