Class 在 PhpStorm 中找到但在 运行 时找不到
Class found in PhpStorm but not when running
我正在使用 PhpStorm 开发 iCal 管理器。
我在用于所有网站的命名空间 Engine
中定义了一个 class User
,在命名空间 User
中定义了一个 class User
=19=] 仅用于 iCal 过程,从 \Engine\User
.
扩展而来
在编码时,PhpStorm 可以找到 \Engine\User
以定义 \iCal\User
,但在执行时我得到了 "Fatal Error: Class \Engine\User not found".
我在 WampServer 上使用带有 PHP 7.2.4 的 PhpStorm 2019.1。
我试图创建一个别名,但没有成功。我试图将我所有的文件都放在一个文件中,然后将其添加到 'Engine' 中,但也没有用。
\Engine\User:
<?php
declare(strict_types=1);
//Created for IGPD by leroy the 27/07/2019
namespace Engine;
use PDO;
use Exception;
use PDOStatement;
/**
* Class User
* @property bool attendee
* @package Engine
*/
class User
{
public function __construct(array $user)
{
$this->email = $user['email'];
$this->name = $user['name'];
$this->surname = $user['surname'];
$this->language = $user['language'];
}
}
\iCal\User:
<?php
declare(strict_types=1);
//Created for IGPD by leroy the 27/07/2019
namespace iCal;
use Engine\User as UserAlias;
/**
* Class User
* @package iCal
*/
class User extends UserAlias
{
public function __construct(array $user, string $cutype, string $role, bool $rsvp, string $partstat, string $sentby, string $dir, string $type)
{
$this->calAddress = "mailto:" . $user['email'];
$this->cutype = in_array($cutype, ['INDIVIDUAL', 'GROUP', 'RESOURCE', 'ROOM', 'UNKNOWN']) ? $cutype : 'UNKNOWN';
$this->role = in_array($role, ['CHAIR', 'REQ-PARTICIPANT', 'OPT-PARTICIPANT', 'NON-PARTICIPANT']) ? $role : 'OPT-PARTICIPANT';
$this->rsvp = $rsvp ? 'TRUE' : 'FALSE';
$this->cn = $user['name'] . " " . $user['surname'];
$this->language = in_array($user['language'], ['EN', 'FR']) ? $user['language'] : 'EN';
$this->partstat = in_array($partstat, ['NEEDS-ACTION', 'ACCEPTED', 'DECLINED', 'TENTATIVE', 'DELEGATED']) ? $partstat : 'NEEDS-ACTION';
$this->sentby = $sentby;
$this->dir = $dir;
$this->type = $type;
UserAlias::__construct($user);
}}
我只是 运行 class 文件来检查错误,所以我应该什么也得不到。
实际输出为:
Fatal error: Class 'Engine\User' not found in D:\wamp\www\IGPD\iCal\User.php on line 12
这里是iCal.php
,需要目录下所有文件的文件:
\iCal\iCal.php:
<?php
declare(strict_types=1);
namespace iCal;
//Created for IGPD by leroy the 02/08/2019
require_once 'Alarm.php';
require_once 'Calendar.php';
require_once 'Event.php';
require_once 'FreeBusy.php';
require_once 'Journal.php';
require_once 'Todo.php';
require_once 'User.php';
然后我在我的主页中使用了它,但它不是我想要加载的那个,所以我不需要它:
\Engine\Engine.php:
<?php
declare(strict_types = 1);
namespace Engine;
session_start();
require_once "collections.php";
require_once "..\iCal\iCal.php";
我不使用自动加载。
我研究了@ÁlvaroGonzález 提到的自动加载解决方案,到目前为止它是唯一可行的解决方案。结果,我想出了这段代码,在我目录根目录的 index.php
中。
\index.php:
<?php
declare(strict_types=1);
namespace iCal;
spl_autoload_register(function ($class){
require_once ucfirst($class) . '.php';
});
$e = new Calendar("e", "e", "e", "r", "e");
$f = new User(['email' => "", 'name'=>"", 'surname'=>"", 'language'=>""], "e", "e", true, "e", "e", "e", "e");
我很高兴地说它有效,但恐怕这不是最好的解决方案,主要是因为如果 class 定义在另一个目录中,则此代码不起作用。
当您 运行 php foo.php
时,PHP 解释器加载该单个文件而不加载其他文件,除非您明确指示它不这样做。另一方面,您的 IDE 不需要 运行 您的代码。它只是扫描您的项目目录,编译所有 classes、函数、常量等,并假设它们在您询问时可用。
任何复杂的程序都需要将代码拆分到多个文件中,因此您需要解决这个问题。几乎所有可用的解决方案都涉及 include
等人。在某种程度上,但细节可能大不相同。同样重要的是要注意,命名空间在 class 或文件加载中没有任何作用——它只是一种机制,随着代码库的增长和第三方库的蓬勃发展,可以使用更多的短名称。
您正在使用直接调用 require_once 来加载文件。这 大致 相当于将包含文件的代码复制并粘贴到 require_once
构造的确切位置,但有一个警告:PHP 独立解析每个文件,如果您正在加载一个 class 定义依赖于另一个 class 的文件,您需要更早地解析其他 classed。看这个例子:
<?php // Animal.php
class Animal
{
}
<?php // Cat.php
class Cat extends Animal
{
}
这个脚本运行完美无缺:
<?php
require_once 'Animal.php';
require_once 'Cat.php';
这会触发 致命错误:未捕获错误:Class 'Animal' not found in C:\tmp\Cat.php:2:
<?php
require_once 'Cat.php';
require_once 'Animal.php';
所以这正是您的问题:您没有以正确的顺序加载文件。
这在相对较小的项目中可能会很棘手,并且不能很好地扩展,因此这就是实施 class auto-loading 的原因。 PHP 提供了一个钩子函数,您可以自定义并在发现需要未知 class 的代码时调用该函数。您的自定义函数获取 class 名称作为参数并执行它认为合适的任何操作(通常涉及 include
调用)。
有些人写了一个关于自动加载器如何工作的规范并称之为 PSR-4. The well-known Composer 包管理器编写了一个实现该规范的自动加载器。因此,如果您在项目中使用 Composer,则无需编写任何代码即可从该自动加载器中受益。您需要做的就是遵循特定的命名约定和目录结构,并定义您的 classes 根目录所在的位置。因此,如果您想要一个名为 \Engine\User
的 class,您可以在位于 /Blah/Blah/Engine/User.php
的文件中定义它,并且 class 在您的代码中使用时会自动加载。
我正在使用 PhpStorm 开发 iCal 管理器。
我在用于所有网站的命名空间 Engine
中定义了一个 class User
,在命名空间 User
中定义了一个 class User
=19=] 仅用于 iCal 过程,从 \Engine\User
.
在编码时,PhpStorm 可以找到 \Engine\User
以定义 \iCal\User
,但在执行时我得到了 "Fatal Error: Class \Engine\User not found".
我在 WampServer 上使用带有 PHP 7.2.4 的 PhpStorm 2019.1。
我试图创建一个别名,但没有成功。我试图将我所有的文件都放在一个文件中,然后将其添加到 'Engine' 中,但也没有用。
\Engine\User:
<?php
declare(strict_types=1);
//Created for IGPD by leroy the 27/07/2019
namespace Engine;
use PDO;
use Exception;
use PDOStatement;
/**
* Class User
* @property bool attendee
* @package Engine
*/
class User
{
public function __construct(array $user)
{
$this->email = $user['email'];
$this->name = $user['name'];
$this->surname = $user['surname'];
$this->language = $user['language'];
}
}
\iCal\User:
<?php
declare(strict_types=1);
//Created for IGPD by leroy the 27/07/2019
namespace iCal;
use Engine\User as UserAlias;
/**
* Class User
* @package iCal
*/
class User extends UserAlias
{
public function __construct(array $user, string $cutype, string $role, bool $rsvp, string $partstat, string $sentby, string $dir, string $type)
{
$this->calAddress = "mailto:" . $user['email'];
$this->cutype = in_array($cutype, ['INDIVIDUAL', 'GROUP', 'RESOURCE', 'ROOM', 'UNKNOWN']) ? $cutype : 'UNKNOWN';
$this->role = in_array($role, ['CHAIR', 'REQ-PARTICIPANT', 'OPT-PARTICIPANT', 'NON-PARTICIPANT']) ? $role : 'OPT-PARTICIPANT';
$this->rsvp = $rsvp ? 'TRUE' : 'FALSE';
$this->cn = $user['name'] . " " . $user['surname'];
$this->language = in_array($user['language'], ['EN', 'FR']) ? $user['language'] : 'EN';
$this->partstat = in_array($partstat, ['NEEDS-ACTION', 'ACCEPTED', 'DECLINED', 'TENTATIVE', 'DELEGATED']) ? $partstat : 'NEEDS-ACTION';
$this->sentby = $sentby;
$this->dir = $dir;
$this->type = $type;
UserAlias::__construct($user);
}}
我只是 运行 class 文件来检查错误,所以我应该什么也得不到。 实际输出为:
Fatal error: Class 'Engine\User' not found in D:\wamp\www\IGPD\iCal\User.php on line 12
这里是iCal.php
,需要目录下所有文件的文件:
\iCal\iCal.php:
<?php
declare(strict_types=1);
namespace iCal;
//Created for IGPD by leroy the 02/08/2019
require_once 'Alarm.php';
require_once 'Calendar.php';
require_once 'Event.php';
require_once 'FreeBusy.php';
require_once 'Journal.php';
require_once 'Todo.php';
require_once 'User.php';
然后我在我的主页中使用了它,但它不是我想要加载的那个,所以我不需要它:
\Engine\Engine.php:
<?php
declare(strict_types = 1);
namespace Engine;
session_start();
require_once "collections.php";
require_once "..\iCal\iCal.php";
我不使用自动加载。
我研究了@ÁlvaroGonzález 提到的自动加载解决方案,到目前为止它是唯一可行的解决方案。结果,我想出了这段代码,在我目录根目录的 index.php
中。
\index.php:
<?php
declare(strict_types=1);
namespace iCal;
spl_autoload_register(function ($class){
require_once ucfirst($class) . '.php';
});
$e = new Calendar("e", "e", "e", "r", "e");
$f = new User(['email' => "", 'name'=>"", 'surname'=>"", 'language'=>""], "e", "e", true, "e", "e", "e", "e");
我很高兴地说它有效,但恐怕这不是最好的解决方案,主要是因为如果 class 定义在另一个目录中,则此代码不起作用。
当您 运行 php foo.php
时,PHP 解释器加载该单个文件而不加载其他文件,除非您明确指示它不这样做。另一方面,您的 IDE 不需要 运行 您的代码。它只是扫描您的项目目录,编译所有 classes、函数、常量等,并假设它们在您询问时可用。
任何复杂的程序都需要将代码拆分到多个文件中,因此您需要解决这个问题。几乎所有可用的解决方案都涉及 include
等人。在某种程度上,但细节可能大不相同。同样重要的是要注意,命名空间在 class 或文件加载中没有任何作用——它只是一种机制,随着代码库的增长和第三方库的蓬勃发展,可以使用更多的短名称。
您正在使用直接调用 require_once 来加载文件。这 大致 相当于将包含文件的代码复制并粘贴到 require_once
构造的确切位置,但有一个警告:PHP 独立解析每个文件,如果您正在加载一个 class 定义依赖于另一个 class 的文件,您需要更早地解析其他 classed。看这个例子:
<?php // Animal.php
class Animal
{
}
<?php // Cat.php
class Cat extends Animal
{
}
这个脚本运行完美无缺:
<?php
require_once 'Animal.php';
require_once 'Cat.php';
这会触发 致命错误:未捕获错误:Class 'Animal' not found in C:\tmp\Cat.php:2:
<?php
require_once 'Cat.php';
require_once 'Animal.php';
所以这正是您的问题:您没有以正确的顺序加载文件。
这在相对较小的项目中可能会很棘手,并且不能很好地扩展,因此这就是实施 class auto-loading 的原因。 PHP 提供了一个钩子函数,您可以自定义并在发现需要未知 class 的代码时调用该函数。您的自定义函数获取 class 名称作为参数并执行它认为合适的任何操作(通常涉及 include
调用)。
有些人写了一个关于自动加载器如何工作的规范并称之为 PSR-4. The well-known Composer 包管理器编写了一个实现该规范的自动加载器。因此,如果您在项目中使用 Composer,则无需编写任何代码即可从该自动加载器中受益。您需要做的就是遵循特定的命名约定和目录结构,并定义您的 classes 根目录所在的位置。因此,如果您想要一个名为 \Engine\User
的 class,您可以在位于 /Blah/Blah/Engine/User.php
的文件中定义它,并且 class 在您的代码中使用时会自动加载。