我正在操纵同一个文件来管理两个外部api类。
一个api类基于命名空间,另一个不是。
我想做的是这样的事情:
if($api == 'foo'){
require_once('foo.php');
}
if($api == 'bar'){
require_once('bar.php');
use xxxx\TheClass;
}
问题在于,当我这样做时,会返回以下错误消息:
Parse error: syntax error, unexpected T_USE in etc...
问题1:我是否必须使用两个不同的文件来管理这两个类,或者在文档中使用命名空间时是否可以同时管理它们?从我看来,它似乎不是。
问题2:为什么命名空间不能在if()语句中使用?
感谢您的帮助
答案 0 :(得分:11)
请参阅Scoping rules for importing
use关键字必须在文件的最外层范围(全局范围)或命名空间内声明中声明。这是因为导入是在编译时完成的,而不是运行时,所以它不能是块作用域。
所有use
都会将符号名称导入当前名称空间。我只是省略导入并使用完全限定的类名,例如
switch ($api) {
case 'foo' :
require_once('foo.php');
$someVar = new SomeClass();
break;
case 'bar' :
require_once('bar.php');
$someVar = new \xxxx\TheClass();
break;
default :
throw new UnexpectedValueException($api);
}
您也可以简单地将use
语句添加到脚本的顶部。添加它不会让您包含任何文件,也不需要知道符号,例如
use xxxx\TheClass;
switch ($api) {
case 'foo' :
require_once('foo.php');
$someVar = new SomeClass();
break;
case 'bar' :
require_once('bar.php');
$someVar = new TheClass(); // imported above
break;
default :
throw new UnexpectedValueException($api);
}
答案 1 :(得分:1)
使用语句应放在任何可执行代码之前(您可以使用命名空间,类,函数和常量定义)。 实际上它只需要无条件地放在某个命名空间中,所以没有if
或内部函数。也不要害怕在顶部使用,它不会加载任何类或实例化对象。它仅作为稍后在执行期间遇到时使用的别名。
至于将它们放在一个文件中,可以在一个文件中包含许多名称空间甚至全局名称空间:
<?php
namespace
{
class myclass{}
}
namespace mynamespace
{
class myclass{}
}
但我强烈反对这种“管理”代码。每个类都应该拥有自己的文件。
答案 2 :(得分:0)
好的,只是确认我说的是真的..尝试这样的事情:
* Test_1.php *
$API = "test_1";
if ($API === "test"){
}elseif ($API === "test_1"){
require ("test.php");
$API = new daryls\testt;
}
$API->test();
test.php的
namespace daryls;
class testt {
public function test(){
echo "Started";
}
}
运行此功能毫无障碍
答案 3 :(得分:0)
API类版本控制的另一个选项是有条件地将类名设置为变量。
// Get class name
switch ($api_version) {
case 'v0':
// No class namespace
$class = 'Handler';
break;
case 'v1':
// Namespaced class
$class = 'API\App\v1\Handler';
break;
case 'v2':
// Namespaced class
$class = 'API\App\v2\Handler';
break;
default:
throw new Exception('Unknown API version: ' . $api_version);
}
// Get class object
$handler = new $class();