【问题标题】:In PHP, how can I wrap procedural code in a class?在 PHP 中,如何将程序代码包装在一个类中?
【发布时间】:2011-05-19 15:20:26
【问题描述】:

我有一大块遗留的 php 代码需要与之交互,如下所示:

//legacy.php

function foo() {
}

function bar() {
}

我希望能够将这些遗留函数包装在一个类中或以某种方式 require_once 而不污染该全局命名空间或更改原始文件。

【问题讨论】:

  • 我建议这是考虑重构的好时机。如果它确实是您所暗示的旧代码,我会说该代码很可能包含一些令人讨厌的东西。你需要在某个时候清理它;现在似乎是一个绝佳的机会。
  • 我给出了答案。很可能它没有说任何你不知道的东西。如果不以某种方式修改文件 AFAIK,没有合理的方法可以做到这一点。
  • @konforce 已经为您提供了解决方案,如果您希望我们提出更可行的解决方案,发布您的一些示例代码可以帮助我们。

标签: php namespaces legacy-code


【解决方案1】:

您可以在类中使用namespace 或静态方法:

// original file: foo.php
class Foo
{
  public static function foo() { }
  public static function bar() { }
}

// new file:
require 'foo.php';

class MyNewClass
{
  public function myfunc()
  {
    Foo::foo();
  }
}

$x = new MyNewClass();
$x->myfunc();

两者都需要对文件稍作修改。例如,使用上述示例(具有静态方法的类),必须将调用 bar() 更改为 Foo::bar()

或者,使用命名空间:

namespace foo;

use \Exception;
// any other global classes

function foo() { }
function bar() { }

在您的文件中:

require 'foo.php';

foo\foo();
foo\bar();

【讨论】:

  • 请注意,使用命名空间可能需要较少的工作...如果代码不使用类,那么您可能只需要顶部的 namespace foo;
  • 我想我不明白你的解决方案。我需要从类内部调用原始的 foo() 或 bar() 函数。
  • @james,以上是对原文件的修改。考虑到这些函数是在不了解您的新代码的情况下编写的,因此无需将它们与您自己的类文件合并。在您编写的任何代码中,您只需将函数称为Foo::bar()。 Spudley 的答案实际上实现起来更简单,但它遇到了与此相同的问题:如果foo() 调用bar(),那么您需要修改原始文件。我建议使用命名空间......这可能是最简单的解决方案。
【解决方案2】:

正如 cmets 中所述,我强烈建议将此视为重构练习的机会。

但假设您出于某种原因不能这样做,您问题的答案取决于原始 legacy.php 文件中的函数是否在内部相互调用。

如果不是,那么是的,做这样的事情相当简单:

<?php
class legacyFunctions {
require_once('legacy.php');
}
?>

但请注意,这只会将它们设置为类中的公共函数,而不是静态的,因此为了调用它们,您必须首先实例化该类的实例,可能在您的代码早期作为全局(这将是单例类的经典示例)。

如果您使用的是 PHP5.3,您可能需要考虑为此使用 PHP namespace 而不是类,这将解决必须实例化类的问题。不过,机制大致相同。

但是,如果您的函数在旧 php 代码中相互调用,那么如果不至少对旧代码进行一些编辑以将函数调用更改为新版本,那么这一切都是不可能的。

【讨论】:

  • 那么执行 require 会将所有这些松散的函数包装为类方法吗?
  • 函数相互调用不是命名空间的问题。但是,引用类(例如 Exception)将停止工作。 (虽然如果这段代码很旧,也许它没有引用任何类。)
  • 我也在使用 php 5.3,命名空间解决方案解决了我一半的问题(命名冲突)
  • 确实会的。语法不会很好,但它会默认使它们成为类的公共方法,所以它会起作用。但是,正如我所说,如果他们互相调用(并且您在对另一个答案的评论中暗示这是这种情况),那么这些函数调用将不再起作用;这才是你面临的真正问题。此外,如果文件中有任何松散的代码(即在任何函数之外),如果将其包含到类中,则会出现语法错误。
  • 鉴于您所说的一切,我认为您将无法避免进行代码更改——只要硬着头皮去做。 :)
猜你喜欢
  • 2018-02-02
  • 1970-01-01
  • 1970-01-01
  • 2016-06-29
  • 1970-01-01
  • 2013-08-11
  • 2014-04-23
  • 2022-11-23
  • 2018-04-23
相关资源
最近更新 更多