【问题标题】:Replacing ::class in PHP 5.4在 PHP 5.4 中替换 ::class
【发布时间】:2017-01-08 14:01:03
【问题描述】:

我正在使用this Composer package 进行需要此包提供的功能的开发。寻找替代方案时,我发现这是我最好的选择,因为可用的替代方案太简单了,无法在我正在处理的时间限制内实施。

现在,我已经在运行 PHP 5.5 的本地机器(在 Windows 10 的 Linux 子系统上)、运行 PHP 5.6 的个人服务器上测试了它,但生产服务器运行的是 PHP 5.4,由于某些原因无法升级。

首先我遇到了这个错误:

Parse error: syntax error, unexpected 'class' (t_class), expecting identifier (t_string) in …

寻找解决方案我打了this question,于是去包代码,发现如下sn-p:

protected static $classmap = [
    'getTransactionResult' => getTransactionResult::class,
    'getTransactionResultResponse' => getTransactionResultResponse::class,
    'transactionResultOutput' => transactionResultOutput::class,
    'cardDetail' => cardDetail::class,
    'wsTransactionDetailOutput' => wsTransactionDetailOutput::class,
    'wsTransactionDetail' => wsTransactionDetail::class,
    'acknowledgeTransaction' => acknowledgeTransaction::class,
    'acknowledgeTransactionResponse' => acknowledgeTransactionResponse::class,
    'initTransaction' => initTransaction::class,
    'wsInitTransactionInput' => wsInitTransactionInput::class,
    'wpmDetailInput' => wpmDetailInput::class,
    'initTransactionResponse' => initTransactionResponse::class,
    'wsInitTransactionOutput' => wsInitTransactionOutput::class
];

我发现 ::class 定义与 PHP 5.4 不兼容,在尝试执行 what the answer to the question suggested 时,我得到了结果 in this commentary to that answer

现在,到目前为止,我已经评论了有问题的行(两者都是 arrays 包含这些 ::class 定义),在生产服务器上进行了测试,并且工作至今。但我想知道这个 ::class 定义是否有实际替代品。

重要提示:我在网上看到的例子是关于get_class('ClassName') 指的是ClassName::class,而不是classMethod::class 案例。我也遇到过this question,但答案中提供的示例并没有让我知道如何使用它。

【问题讨论】:

  • PHP 5.4 已在将近一年前终止。现在在生产环境中运行非常不安全升级php.net/eol.php
  • 您使用的是unsupported End-Of-Life version of PHP。不幸的是,这意味着您缺乏支持。解决问题的最佳方法是升级 PHP 或使用支持 PHP 5.4 的库。真的没有什么除了告诉你之外,这里的任何人都可以为你做。
  • @ceejayoz 感谢您的及时建议,但这是我和系统管理员已经知道的。到目前为止,作为开发人员,我对此无能为力,因为它是一个运行太多遗留脚本的遗留服务器。有一个新的生产服务器的计划,但它不在近期的计划中。
  • 我想指出 PHP 5.4 仍然是 RHEL/CentOS 提供的主要版本,他们正在向后移植安全补丁并维护他们的版本。我很惊讶人们以“安全性”为由盲目地建议迁移到供应商未维护的版本。这实际上恰恰相反,像 RedHat 这样的供应商有预算和团队来确保安全补丁被反向移植,而大多数 3rd 方存储库只是构建最新版本,并没有评估或解决安全风险。跨度>

标签: php composer-php php-5.4


【解决方案1】:

::class 返回该类的完整命名空间。您可以改为编写完整的命名空间。在一些新包中,如果需要,最好将命名空间赋予一个类并在该类中创建实例。 ::class 更短更舒适。

例如:

protected static $classmap = [
    'getTransactionResult' => 'Namespace\of\the\class',
]

这要长得多,当你在那个位置遇到这样的问题时,我相信你在使用新包时会遇到更多问题。

【讨论】:

  • 感谢您的回答。有没有办法知道一个类的完整命名空间?如果我可以在我的本地机器中获得完整的命名空间,我可以编辑代码以使其工作。
  • @noquierouser 只需打开类文件检查类的命名空间即可。它应该在上面。也看看secure.php.net/manual/en/language.namespaces.php
  • 我在文件顶部有所有这些use。这些是我应该使用的吗? A capture of all the use clauses
【解决方案2】:

您只需将数组值替换为类的完全限定名称。 假设类Example 有命名空间foo\bar 而不是写Example::class 只是写foo\bar\Example

【讨论】:

  • 这不是 OP 的代码,但它是 Composer 包的代码。在任何类型的 Composer 驱动的构建/部署过程中,这些更改都会被吹走。
  • @ceejayoz:但我只在本地机器上使用 Composer,因为我没有 SSH 访问生产环境来运行 Composer。所以编辑包的代码是一种选择。
  • @noquierouser 这可能是 fork 项目的更好方法。
  • @noquierouser 附注 - 您在生产中不需要 作曲家 - 您可以在本地运行它并将您的依赖项提交到您的项目中。有些人认为这是一种更有弹性的部署方法,因为您不依赖外部可用性来进行这种部署。
猜你喜欢
  • 2013-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
相关资源
最近更新 更多