当创建一组函数(例如创建页眉,页脚和其他布局函数)时,我应该使用具有所有这些函数的类作为方法还是我可以将所有函数声明为全局函数?
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的新手,我对最佳实践非常好奇。所以我正在学习,我无法在网上找到关于这一个的内容,我无法理解这一点。请帮帮我!!!
答案 0 :(得分:3)
这更好地视为意见而不是回答,好吧,我说过。
TL; DR
如果你对扩展有足够的关注,你会发现OOP的类很方便。您应该考虑的另一件事是,您的代码看起来会更清晰。这篇文章展示了以OOP方式维护PHP代码是多么容易。如果你正在寻找真正的答案,请跳到这篇文章的末尾
正如您所说(或与?混淆),此类静态类的使用仍将作为全局函数。这就是为什么,主要是我用它们作为助手,工具等。 但这根本不是真的。每个编程语言中都存在一个名为Design Pattern的东西。如果您以正确的方式遵循它,您将发现代码的强大和清晰。
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
类到一种&#34; real&#34;的逻辑。类。
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 文件。我不应该全部渲染!然后我问自己,&#34;我应该重写我的Render
课程吗?&#34; 在几秒钟内思考...分钟......已经......甚至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中逐个包含,而不是通过 script.php 将其全部列在HTML {{ 1}}标签。
所谓的&#34;逻辑&#34; class是
<script>
我延长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
方法以确保我是否获得javascript文件(isScript()
扩展名)或否。最后,实用程序类来了。
.js
以this answer之类的javascript HTML标记结尾非常简单。
唷!无法等待抓住这个新功能运行!现在我的 view 文件看起来就像这个
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>';
}
}
如果我想......等等......你知道的!我只需要在某些文件上调整我的部分代码。它简单易行。
<!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>
例如,如果我想在页脚上添加一些很酷的功能怎么办?是!只需打破整个页脚文件的代码!如果我想在标题中添加一些逻辑怎么办?简单!只需创建另一个功能!
答案 1 :(得分:1)
为什么不这样:
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();
答案 2 :(得分:1)
在全局空间中创建它们不是最佳做法。您的代码应该是模块化的,并且应尽可能使用类。
此外,您应该使用一个php框架,它可以为您的代码提供大量动态功能。这将使您的代码可重用,可扩展且易于测试。
在全局空间中使用纯PHP可以充分利用语言的许多功能,例如名称空间。当代码增长时,这也会影响可读性。
答案 3 :(得分:1)
我认为这一切都取决于你正在使用的范例。据我所知,PHP支持面向对象,所以如果你要使用OOP,最好使用对象而不是全局方法。另外,如果已经多次实例化类,使用静态方法是一种好方法,但我更喜欢这个:
class Page{
public function render_header(){
//do sth
}
public function render_footer(){
//do sth
}
public function render_script(){
//do sth
}
public function render(){
/* render all page sections
render_script()
render_header()
render_footer() */
}
}
然后轻松实例化Page class:
$page = new Page();
$page->render();