php - 类方法或全局函数

标签 php function oop

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

P.s.如果语言很重要,我正在使用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的新手,我对最佳实践感到很好奇。因此,我正在学习,并且无法在网上找到有关此的信息,也无法从中脱颖而出。请帮我!!!

最佳答案

我说的是,最好将其视为意见而不是答案。


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接口的类中插入一个对象。而且,一切都完成了!我只需要在我的视图文件中实例化它,我将其命名为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();




哦,快点!我忘记了,我没有身体锉。我不应该全部渲染!然后我问自己:“我应该重写我的Render类吗?”在几秒钟内思考...几分钟...已经几个小时...甚至三天,就知道了!也许以后我会发现它有用,让我们创建一个其他方法来帮助我解决当前问题。

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 <script>标记的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>';
    }
}


它确实很简单,以这样的javascript HTML标记结尾。

!等不及要抓住这个新功能了!现在我的视图文件将完全像这样

<!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';
}


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

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


this answer
What's the benefit of object-oriented programming over procedural programming?
simple explanation PHP OOP vs Procedural?
Stop using global in PHP
Defining OOP for a new programmer
PHP: Real world OOP example

关于php - 类方法或全局函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37833499/

相关文章:

php - 如何更改主 div 中打印的 div 的顺序?

javascript - jQuery 暂停函数执行并在暂停时执行其他操作

objective-c - OOP:设计菜单系统

matlab - 使用 MATLAB 中的其他类访问方法

c++ - 向下转换实际上有用吗?

PHP MYSQL 在数据库 0.01 中保存 float ?

php - 生成错误 INSERT 语句的 Doctrine

php - 在 CodeIgniter (MVC) 中从内容文件设置页面标题

ios - 正确调用 swift 中的函数

c++ - 成员函数模板,其参数数量取决于一个完整的模板参数