【问题标题】:Class method or global function类方法或全局函数
【发布时间】:2016-10-16 10:54:13
【问题描述】:

在创建函数组(例如创建页眉、页脚和其他布局函数)时,我应该使用具有所有这些函数的类作为方法,还是可以将所有函数声明为全局函数?

附:如果语言很重要,我正在使用 PHP。

编辑 - 添加更多描述

好的,这就是我想要做的。 比方说,我想创建 3 个函数,这些函数将在我的项目中重复使用,

  • render_header(回显页面的标题部分)

  • render_footer(回显页面的页脚部分)

  • render_script(在页面中回显脚本文件链接)

所有都在做创建部分的html页面。 所以,起初我在想我应该把它们放到一个类中,并将其用作类的方法。

例如。我可能会在 layout.php 中编写以下代码

class layout{

public static function render_header(){
        //do sth
}

public static function render_footer(){
        //do sth
}

public static function render_script(){
        //do sth
}

}

再想一想,我在想我是否应该只创建一个全局函数并将文件包含在我想要使用的页面中。

例如。我可能会在 layout.php 中编写以下代码

function render_header(){
        //do sth
}

function render_footer(){
        //do sth
}

function render_script(){
        //do sth
}

据我所知,这两种方法我需要做的就是将文件包含在我想要的页面中并调用类的静态函数或直接调用函数。

所以我的问题是,如果你和我一样,你会选择哪一个?

感谢您的宝贵时间。我是 php 新手,我对最佳实践非常好奇。所以我正在学习,我无法在网上找到关于这个的信息,我也无法忘记这个。请帮帮我!!!

【问题讨论】:

  • 你的问题很不清楚。请考虑添加一些您编写的代码。
  • 您尝试完成的示例将缩小问题范围。

标签: php function oop


【解决方案1】:

这最好作为意见而不是回答,好吧,我说过。

TL;DR

如果您足够关心扩展,您会发现带有类的 OOP 非常方便。您应该考虑的另一件事是,您的代码看起来会更干净。这篇文章展示了以 OOP 方式维护 PHP 代码是多么容易。如果您正在寻找真正的答案,请跳至本文末尾

正如您所说(或混淆?),此类静态类的使用将保持为全局函数。这就是为什么我主要将它们用作助手、实用程序等。 但事实并非如此。每种编程语言中都有一个叫做Design Pattern 的东西。如果你以正确的方式遵循它,你会发现你的代码看起来是多么的强大和清晰。

Utils.php

class Assets
{
    public static function js($url)
    {
        return '<script src=" . $url . "></script>';
    }
}

//Usage: 
//Assets:js('htps://cdn.bootshake.com/1.2.3/bootshake.min.js');

除了帮助其他班级构建/布局您的服务器站点结构之外,与它无关。

因为我关心未来,所以我会一直尽量避免硬编码;重构整个代码只是为了添加一个新特性;一旦发现错误,就破坏整个站点。从那时起,作为这个星球上最直观的人,我经常想象我的网站最终会是什么样子,把我的整个逻辑分成我能做的最小的块。


示例实现

我尝试创建一个合同,其中我的页面布局看起来如何。我只会从中受益于type hinting

interface Layout
{
    public function __construct($page);
    public function render();
}

让我们从这个类创建一个简单的逻辑。它只会检查文件是否存在并且include它。

class Page implements Layout
{
    public $file;

    public function __construct($file)
    {
        $this->file = $file;
    }

    public function render()
    {   
        $file = $this->file;

        if (! file_exists($file)) {
            throw new Exception($file . "doesn't exists");
        }
        //render it
        include $file;
    }
}

我将为我想要包含的每个文件实例化这个类,在这种情况下它们是你提到的三个,页眉、页脚和脚本。让我们实现从Page 类到一种“真实”类的逻辑。

class Render
{
    private $header;
    private $footer;
    private $script;

    public function __construct(Layout $header, Layout $footer, Layout $script)
    {
        $this->header = $header;
        $this->footer = $footer;
        $this->script = $script;
    }

    public function header()
    {
        return $this->header->render();
    }

    public function footer()
    {
        return $this->footer->render();
    }

    public function script()
    {
        return $this->script->render();
    }

    public function all()
    {
        $this->header();
        $this->footer();
        $this->script();
    }
}

请注意,我在构造函数中输入了Layout 接口。它会向我保证,我将始终从实现Layout 接口的类中插入一个对象。而且,一切都完成了!我只需要在我的 view 文件中实例化它,我将它命名为 index.php

$header = new Page('public/header.php');
$footer = new Page('public/footer.php');
$script = new Page('public/script.php');

$render = new Render($header, $footer, $script);
$render->all();

哦,快!我忘记了,我没有我的 body 文件。我不应该全部渲染!然后我问自己,“我应该重写我的 Render 课程吗?” 想几秒钟……几分钟……几小时……甚至 3 天,明白了!我以后可能会发现它很有用,现在让我们创建另一种方法来帮助我解决这个问题。

class Render
{
    ....
    ....
    ....

    public static function page(Layout $file)
    {
        return $file->render();
    }
}

然后在我的 index.php 文件中,我将:

<!doctype html>
<html>
    <?php Render::page(new Page('public/header.php')); ?>
    <body>
        <h1>Holle Werld!</h1>
        <?php Render::page(new Page('public/footer.php')); ?>
        <?php Render::page(new Page('public/script.php')); ?>
    </body>
</html>

这看起来不像OP在想什么吗?一直都是静态类?好吧,也许吧。但不是!我觉得不行。我有一些逻辑可以在Page 类中轻松维护。


2 个月过去了,我想将我的所有脚本文件更改为可用的公共 CDN,并在其 CDN 在客户端无法访问时执行回退。很棒的功能不是吗?在这种情况下,我会将我的脚本文件分开,并从assets/js 文件夹和CDN 中将其一一包含,而不是通过带有HTML &lt;script&gt; 标签的script.php 将它们全部列出。

所谓的“逻辑”类是

class Script extends Page
{
    public function render()
    {
        if (! $this->isScript()) {
            throw new Exception($this->file . "needs to be script");
        }

        if (! file_exists($this->file)) {
            throw new Exception($this->file . "doesn't exists");
        }

        return CDN::fallback($this->file);
    }

    protected function isScript()
    {
        return pathinfo($this->file, PATHINFO_EXTENSION) === 'js';
    }
}

我扩展Page类的原因是因为我不需要创建相同的方法和构造函数,也不需要键入implements Layout,因为父类已经实现了它。然后,我创建了isScript() 方法来确保我是否获得了 javascript 文件(.js 扩展名)。最后,实用类来了。

class CDN
{
    protected static $path = 'public/assets/js';

    public static function fallback($file)
    {
        $script = explode(self:$path, $file);
        $script = end($script);
        $script = explode('/', $script);

        $library = $script[0];
        $name = end($script);
        $version = preg_match('/\d+(?:\.\d+)+/', $script, $matches);
        $version = $matches[0];

        return '<script src="//mincdn.com/' . $version . '/' . $name . '"></script>' .
        '<script>window. ' $library ' . || document.write(\'<script src="' . $script . '"><\\/script>\')</script>';
    }
}

它确实很简单,以 this answer 之类的 javascript HTML 标记结尾。

呸!迫不及待地想抓住这个新功能!现在我的 view 文件看起来就像这个

<!doctype html>
<html>
    <?php Render::page(new Page('public/header.php')); ?>
    <body>
        <h1>Holle Werld!</h1>
        <?php Render::page(new Page('public/footer.php')); ?>
        <?php Render::page(new Script('public/assets/js/qJuery/1.2.3/qJuery.min.js')); ?>
        <?php Render::page(new Script('public/assets/js/bootshake/1.2.3/bootshake.min.js')); ?>
    </body>
</html>

如果我想……等等……怎么办?你知道的!我只需要在某些文件上调整我的部分代码。它既简单又干净。


比较

function header($file)
{
    include 'header.php';
}
function footer($file)
{
    include 'footer.php';
}
function script($file)
{
    include 'script.php';
}

例如,如果我想在页脚添加一些很酷的功能怎么办?是的!只需破坏整个页脚文件的代码!如果我想在标题中添加一些逻辑怎么办?简单的!只需创建另一个函数!

那么有什么不同呢?他们来了,

【讨论】:

    【解决方案2】:

    全局空间中创建它们并不是最佳做法。您的代码应该是模块化的,并且应该尽可能使用类。

    您还应该使用一个 php 框架,该框架使您的代码具有很多动态能力。这将使您的代码可重用、可扩展且易于测试。

    在全局空间中使用纯 php 会使您无法充分利用语言的许多特性,例如命名空间。当您的代码增长时,这也会影响可读性。

    【讨论】:

      【解决方案3】:

      为什么没有这样的东西:

      class Page {
      
          private function render_header(){
                  //do sth
          }
      
          private function render_footer(){
                  //do sth
          }
      
          private function render_script(){
                  //do sth
          }
      
          public function render() {
              //combine above methods to a page...
          }
      
      }
      

      然后

      $page = new Page();
      echo $page->render();
      

      【讨论】:

        猜你喜欢
        • 2012-03-01
        • 1970-01-01
        • 2019-03-22
        • 1970-01-01
        • 2019-06-23
        • 2022-01-24
        • 1970-01-01
        • 1970-01-01
        • 2017-03-11
        相关资源
        最近更新 更多