如何正确导入多个命名空间

时间:2014-06-19 20:53:43

标签: php symfony namespaces

我是PHP名称空间的新手,我有一个问题:

如果我们使用'use'命令导入多个名称空间,我们不应该遇到问题吗? 我一直在阅读这篇文章http://www.sitepoint.com/php-namespaces-import-alias-resolution/,在关于命名空间导入的部分中,它说你仍然需要在函数旁边有一个合格的前缀(即:Lib2),但在查看一些Symfony 2示例时文件,我没有看到发生这种情况。 命名空间如何解决(在下面的示例文件中)解决名称冲突?

namespace Acme\DemoBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Acme\DemoBundle\Form\ContactType;

// these import the "@Route" and "@Template" annotations
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;

class DemoController extends Controller
{
/**
 * @Route("/", name="_demo")
 * @Template()
 */
public function indexAction()
{
    return array();
}

/**
 * @Route("/hello/{name}", name="_demo_hello")
 * @Template()
 */
public function helloAction($name)
{
    return array('name' => $name);
}

/**
 * @Route("/contact", name="_demo_contact")
 * @Template()
 */
public function contactAction(Request $request)
{
    $form = $this->createForm(new ContactType());
    $form->handleRequest($request);

    if ($form->isValid()) {
        $mailer = $this->get('mailer');

        // .. setup a message and send it
        // http://symfony.com/doc/current/cookbook/email.html

        $request->getSession()->getFlashBag()->set('notice', 'Message sent!');

        return new RedirectResponse($this->generateUrl('_demo'));
    }

    return array('form' => $form->createView());
}
}

2 个答案:

答案 0 :(得分:2)

我认为误解来自帖子的文件名。请记住:

  • 带有namespace Acme/AcmeBundle/Controller/的DefaultController.php将包含在use Acme/AcmeBundle/Controller/DefaultController

  • 带有namespace Acme/AcmeBundle/Controller2/的DefaultController2.php将包含在use Acme/AcmeBundle/Controller2/DefaultController2

要发生冲突,您需要包含两个名为DefaultController.php的文件

  • 带有namespace Acme/AcmeBundle/Controller
  • 的DefaultController.php
  • 带有namespace Acme/AcmeBundle/Controller2
  • 的DefaultController.php

然后需要凯文指出的别名

  • namespace Acme/AcmeBundle/Controller的DefaultController.php => use Acme/AcmeBundle/Controller/DefaultController
  • namespace Acme/AcmeBundle/Controller2的DefaultController.php => use Acme/AcmeBundle/Controller2/DefaultController as DefaultController2

答案 1 :(得分:0)

解释这个问题的最佳方法可能是从命名空间解析开始向后工作。

假设您有以下行:

$newFoo = new Foo();

PHP将查看类Foo的当前符号表。该符号表包括当前名称空间和任何导入(使用)名称空间(以及内置PHP符号)。

例如,假设类Foo在Foo.php中声明:

<?php //Baz/Foo.php
namespace Baz\Foo;

class Foo{}

如果您在Bar.php工作,可以参考以下内容:

<?php //Baz/Bar.php
namespace Baz\Bar;
use Baz\Foo;
//The following lines are equivalent
$newFoo = new Foo\Foo(); //Local namespace
$newFoo = new \Baz\Foo\Foo(); //Fully qualified namespace

您也可以在使用中直接引用Foo类,而不是引用Foo命名空间。

<?php //Baz/Bar.php
namespace Baz\Bar;
use Baz\Foo\Foo;
//The following lines are equivalent
$newFoo = new Foo(); //Local namespace
//$newFoo = new Foo\Foo(); //This will fail, as the symbol Foo is a class, not a namespace
$newFoo = new \Baz\Foo\Foo(); //Fully qualified namespace still works.

如果您想直接引用Namespace和Class Foo,则需要使用Alias解决冲突。

<?php //Baz/Bar.php
namespace Baz\Bar;
use Baz\Foo;
use Baz\Foo\Foo as FooClass;
//The following lines are equivalent
$newFoo = new FooClass(); //Notice the new aliased symbol.
$newFoo = new Foo\Foo(); //This works now.
$newFoo = new \Baz\Foo\Foo(); //Fully qualified namespace still works.
//$newFoo = new \Baz\Foo\FooClass(); //This will fail, aliases don't work for fully qualified names.

另外,比如说,除了你的Baz / Foo.php文件,你还有一个Bar / Foo.php文件:

<?php //Bar/Foo.php
namespace Bar\Foo;

class Foo{}

如果您想在本地引用这两个命名空间,则需要使用别名来解决名称冲突:

<?php //Baz/Bar.php
namespace Baz\Bar;
use Baz\Foo as Foo1;
use Baz\Foo\Foo as Foo1Class;
use Bar\Foo as Foo2;
use Bar\Foo\Foo as Foo2Class;
//The following lines are equivalent, referencing Baz\Foo\Foo
$newBazFoo = new Foo1Class(); //Object alias.
$newBazFoo = new Foo1\Foo();  //Namespace alias.
$newBazFoo = new \Baz\Foo\Foo(); //Fully qualified namespaces don't need any aliases.
//The following lines are equivalent, referencing Bar\Foo\Foo
$newBarFoo = new Foo2Class(); //Object alias.
$newBarFoo = new Foo2\Foo();  //Namespace alias.
$newBarFoo = new \Bar\Foo\Foo(); //Fully qualified namespaces don't need any aliases.

除了使用use语句导入Namespace之外,还需要包含包含该命名空间的文件。这可以使用require_once()手动完成,但通常由自动装带器自动处理。

有关详细信息,请参阅Symfony Class Loader

希望有所帮助。