我是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());
}
}
答案 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
namespace Acme/AcmeBundle/Controller2
然后需要凯文指出的别名
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。
希望有所帮助。