9

我正在操作同一个文件来管理两个外部 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() 语句中使用命名空间?

谢谢您的帮助

4

4 回答 4

18

请参阅导入的范围规则

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);
}
于 2013-11-11T23:30:38.590 回答
1

Use 语句应该放在任何可执行代码之前(可以有命名空间、类、函数和常量定义)。 实际上它可以,只需无条件地放置在某个命名空间中,因此没有ifs 或内部函数。也不要害怕将 use 放在顶部,它不会加载任何类或实例化对象。它仅充当稍后在执行期间遇到时使用的别名。

至于将它们放在一个文件中,可以在一个文件中拥有多个命名空间甚至全局命名空间:

<?php   
namespace
{
    class myclass{}
}
namespace mynamespace 
{
    class myclass{}
}

但我强烈反对这种对代码的“管理”。每个类都应该有自己的文件。

于 2013-11-11T23:32:05.653 回答
0

好吧,只是确认我说的是真的..试试这样的:

*Test_1.php*

$API = "test_1";
if ($API === "test"){

}elseif ($API === "test_1"){
    require ("test.php");
    $API = new daryls\testt;
}

$API->test();

测试.php

namespace daryls;
class  testt {
    public function test(){
        echo "Started"; 
    }
}

运行它很顺利

于 2013-11-11T23:25:41.110 回答
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();
于 2016-09-06T23:57:39.427 回答