This better taken as opinion rather than answer, well, I said that.
TL;DR
If you care enough about scaling, you'll find OOP with classes much convenient to do it. Another thing you should consider is, your code will look much cleaner. This post is showing how easy to maintain PHP codes in OOP way. Jump to end of this post if you're looking for the real answer
As you stated (or confused with?), usage of such static classes will remain as global function. That's why, mostly I use them as a helper, utils, or such. But that's not true at all. There's a thing called Design Pattern that exists in every programming languages. If you follow it in the correct way, you'll find how strong and clear your codes look like.
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');
There's nothing to do with it but helping the other class to build/layouting your server site structure.
Since I care about the future, I will always try to avoid hardcoding; refactoring whole codes just for adding a new feature; break the whole site once a bug found. Since then, by being most intuitive person in this planet, I often imagine what would my site looks exactly in the end, by separating my whole logic into tiniest chunks I could make.
Sample Implementation
I try to create a contract of which how my page layout look. I'll only take the benefit from type hinting from this.
interface Layout
{
public function __construct($page);
public function render();
}
Let's create a simple logic from this class. It will only check if the file does exist and include
it.
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;
}
}
I will instantiate this class for every file I want to include, in this case they are the three you mention, header, footer and script. Let's implement the logic from Page
class to one kind of "real" class.
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();
}
}
Notice that I type-hint the Layout
interface into the constructor. It'll assure me that I'll always insert an object from a class that implement Layout
interface. And, It's all done! I just need to instantiate it in my view file, I'll name it 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();
Oh snap! I forgot about it, I don't have my body file. I shouldn't render it all! I then ask myself, "should I rewrite my Render
class?" Thinking in seconds... minutes... hours already ...even 3 days, got it! I maybe found it useful later, let's just create another method to help me fix this issue, currently.
class Render
{
....
....
....
public static function page(Layout $file)
{
return $file->render();
}
}
Then in my index.php file, I'll just:
<!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>
Doesn't it looks like what OP thinking about? Static class all the way? Well, maybe. But, NO! I think no. I have some logic I could maintain easily at Page
class.
2 months passed, and I want to change all my script files to available public CDN and perform a fallback if its CDN uncreachable on client end. Great feature doesn't it? In this case I'll separate away my script files, and include it one by one from assets/js
folder and CDN, instead of list them all through script.php with HTML <script>
tag.
The so called "logic" class is
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';
}
}
The reason why I extend Page
class is because I don't need to create same method and constructor and I don't need to type implements Layout
since the parent class already implemented it. Then so, I create isScript()
method to assure whether I get javascript file (.js
extension) or no. In the end, here come the utility class.
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>';
}
}
It does really simple thing that end in javascript HTML tag like this answer.
Phew! Can't wait to grab this new feature running! Now my view file will exactly looking like this one
<!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>
What if I want to.... blah.... ? You know it! I just need to tweak some part of my code on certain file. It's easy and cleaner.
Comparing
function header($file)
{
include 'header.php';
}
function footer($file)
{
include 'footer.php';
}
function script($file)
{
include 'script.php';
}
What if I want to add some cool features on footer, for example? Yes! Just break the whole footer file's code! What if I want to add some logic to the header? Simple! Just create another function!
So what's the different? Here they are,