我正在编写一堆通用但相关的函数供不同的对象使用。我想对这些函数进行分组,但我不确定是否应将它们放在一个类或简单的平面库文件中。
像一个类一样对待它们似乎并不正确,因为没有一种对象可以使用它们,这样一个包含所有这些函数的类可能不一定具有任何属性。
将它们视为一个平面库文件似乎太简单了,因为缺少一个更好的词。
最佳做法是什么?
答案 0 :(得分:6)
查看名称空间:
http://www.php.net/manual/en/language.namespaces.rationale.php
将它们包装在无用的类中是命名空间概念的变通方法实现。此概念允许您避免与大型项目或插件/模块类型部署中的其他功能发生冲突。
修改强>
坚持使用PHP 5.2?
使用单独的文件来组织实用程序功能没有任何问题。请务必使用注释记录它们,这样您就不会得到bunchafunctions.php
,这是一个可疑目的的20,000个程序代码文件。
前缀也没有错。使用前缀是组织类似目的函数的另一种方法,但一定要避免使用该语言已经保留的这些“伪命名空间”。具体来说,PHP [reference]保留“__”作为前缀。要特别小心,如果您担心来自其他库的冲突函数,您还可以在function_exists
检查中包装函数声明:
if (!function_exists('myFunction')) {
function myFunction() {
//code
}
}
您还可以重新考虑对象结构,也许这些实用程序函数更适合作为基类中所有其他对象都可以扩展的方法。看一下继承:http://www.php.net/manual/en/language.oop5.inheritance.php。基类模式是一个常见且非常有用的模式:
abstract class baseObject {
protected function doSomething () {
print 'foo bar';
}
public function getSomething () {
return 'bar foo';
}
}
class foo extends baseObject {
public function bar () {
$this->doSomething();
}
}
$myObject = new foo();
$myObject->bar();
echo $myObject->getSomething();
您可以在此处试验上述代码:http://codepad.org/neRtgkcQ
答案 1 :(得分:2)
在这种情况下,我会使用带static
方法的类:
class Tools {
static public function myMethod() {
return 1*1;
}
}
echo Tools::myMethod();
修改强>
正如Chris和yes123已经提到的:如果主机已经运行 PHP 5.3 + ,您应该考虑使用namespace
。如果您不确定是否值得切换到命名空间,我建议阅读Matthew Weier O'Phinney的文章Why PHP Namespaces Matter。
修改强>
尽管将静态方法的使用概括为“坏习惯”或“废话”并未解释为什么他们认为它是这样的 - 哪种imo会更具建设性 - 他们仍然让我重新思考和重读。
典型的论点是,静态方法可以创建依赖关系,因此可以使单元测试和类重命名成为不可能。
如果根本不使用单元测试(可能是家庭/个人使用的编程,或者低预算项目,没有人愿意支付单元测试实施的额外成本),这个论点当然会变得过时。
即使使用单元测试,也可以使用$var::myMethod()
来避免创建静态方法依赖项。所以你仍然可以使用模拟并重命名该类......
尽管如此,我得出结论,我的答案过于笼统。
我认为我应该写得更好:这取决于。
由于这很可能导致在技术上可行的所有不同解决方案以及数十种可能的场景和环境的利弊得到开放式辩论,我不愿意进入这一点。
我现在赞成克里斯的回答。它已经涵盖了大多数技术可能性,应该为您服务。
答案 2 :(得分:2)
我通常会将它们粘贴在一个类中并标记方法static
。您可以将其称为静态类,即使PHP实际上没有这样的东西(您不能将static
关键字放在类的前面)。它仍然比全局函数更好,因为您可以避免可能的命名冲突。该类成为一种命名空间,但PHP也有自己的命名空间,可能更适合您的目的。
您甚至可能会发现确实可以添加属性,即使它们也是静态的,例如延迟加载的辅助对象,缓存信息等。
答案 3 :(得分:1)
将它们作为一个类进行处理确实可以为您提供命名空间的好处,尽管您可以通过像PHP一样为array_*
函数添加前缀来实现相同的功能。由于您没有任何属性,这基本上意味着您的所有方法都是静态的(如Class::method()
)。这在Java中并不常见。
通过使用类,您还可以在必要时从父类或接口继承。这方面的一个例子可能是为函数可能返回的错误代码定义的类常量。
编辑:如果PHP 5.3+可用,则命名空间功能非常理想。但是,PHP版本仍然落后于许多主机和服务器,尤其是运行企业级稳定Linux发行版的那些主机和服务器。
答案 4 :(得分:0)
我已经看到了几种不同的方式,都有他们的疣,但都适用于他们被利用的特定项目。
答案 5 :(得分:0)
是的,正式可以......任何类都是方法+属性。但是当你在课堂上打包一些功能时 - 它会变得不理想的OOP。如果你有一堆函数,那些是分组的,但没有使用过一些类变量 - 看起来,你有某个设计问题。
我现在的感觉是“休斯顿,我们有问题”。
答案 6 :(得分:0)
如果你使用的函数完全正确,有一个理由将它们包装在静态类中 - autoloader 。
当然,它会产生高耦合,并且可能不适合测试(并不总是),但是......在这种情况下,简单函数并不比静态类好:)同样高耦合等。
在理想的OOP架构中,所有函数都是某些对象的方法。这只是乌托邦,但我们应该尽可能地建立理想的建筑。
答案 7 :(得分:-1)
编写一堆“通用但相关”的函数通常是个坏主意。很可能你没有看到足够明确的问题来创建适当的对象。
不好的想法不是因为它是“不理想的OOP”。它根本不是OOP。
克里斯带来的“基类模式”是另一个坏主意 - 谷歌:“赞成合成而不是继承”。 使用function_exists('myFunction')“非常小心”并不是想法。这是一场噩梦。 即使在现代的javascript中,目前也避免使用这种代码......